I am having a problem with merging two activities in Android Studio. I am new to coding and I know this should be relatively simple but I am slowly learning, so bear with me.
Basically my starting activity was a sample app that came with the IOIO development board. I have modified this to work for my application. I also have a MAX31855 thermocouple amplifier that I have found code for and it is working perfect, the only problem is that all of the code is in a separate activity from my sample app activity. So both will not run at the same time on my simple one screen app. So now I am trying to merge the thermocouple amplifier code into the sample app code. How should I start going about this? I have attached the code for both activities below.
The code for the sample app:
package ioio.examples.simple;
import ioio.lib.api.AnalogInput;
import ioio.lib.api.DigitalOutput;
import ioio.lib.api.IOIO;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import ioio.lib.api.SpiMaster;
import ioio.lib.api.SpiMaster.Rate;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
import java.util.ArrayList;
import java.util.List;
public class IOIOSimpleApp extends IOIOActivity {
private TextView boost;
private TextView fuelpressure;
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
enableUi(false);
}
class Looper extends BaseIOIOLooper {
private AnalogInput boost, fuelpressure;
#Override
public void setup() throws ConnectionLostException {
boost = ioio_.openAnalogInput(45);
fuelpressure = ioio_.openAnalogInput(42);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
setNumber1(38.314 * ((boost.getVoltage() - 0.27)));
setNumber2(38.314 * ((fuelpressure.getVoltage() - 0.27)));
Thread.sleep(200);
}
#Override
public void disconnected() {
enableUi(false);
}
}
#Override
protected IOIOLooper createIOIOLooper() {
return new Looper();
}
private void enableUi(final boolean enable) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//seekBar_.setEnabled(enable);
//toggleButton_.setEnabled(enable);
}
});
}
private void setNumber1(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
boost.setText(str);
}
});
}
private void setNumber2(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
fuelpressure.setText(str);
}
});
}
}
And the code for the thermocouple amplifier:
package ioio.examples.simple;
import ioio.lib.api.SpiMaster;
import ioio.lib.api.SpiMaster.Rate;
import ioio.lib.api.exception.ConnectionLostException;
import ioio.lib.util.BaseIOIOLooper;
import ioio.lib.util.IOIOLooper;
import ioio.lib.util.android.IOIOActivity;
import ioio.lib.api.AnalogInput;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends IOIOActivity {
protected static final float FAULT_DISPLAY_DURATION = 10; // seconds
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
private TextView boost;
private TextView fuelpressure;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
}
#Override
protected IOIOLooper createIOIOLooper() {
int sdoPin = 1; // DO
int sdaPin = 29; // we do not use this pin but the IOIOLib requires we specify it, so we pick an unused pin
int sclPin = 2; // CLK
int csPin = 3; // CS
Rate rate = SpiMaster.Rate.RATE_31K;
final MAX31855 max31855 = new MAX31855(sdoPin, sdaPin, sclPin, csPin, rate);
max31855.setListener(new MAX31855.MAX31855Listener() {
private long faultTime;
#Override
public void onData(float internal, float thermocouple) {
updateTextView(internalText, "Internal = " + internal + " C");
updateTextView(thermocoupleText, thermocouple + " C");
float secondsSinceFault = (System.nanoTime() - faultTime) / 1000000000.0f;
if (secondsSinceFault > FAULT_DISPLAY_DURATION) {
updateTextView(faultsText, "Faults = ");
}
}
#Override
public void onFault(byte f) {
List<String> faults = new ArrayList<String>();
if ((f & MAX31855.FAULT_OPEN_CIRCUIT_BIT) == MAX31855.FAULT_OPEN_CIRCUIT_BIT)
faults.add("Open Circuit");
if ((f & MAX31855.FAULT_SHORT_TO_GND_BIT) == MAX31855.FAULT_SHORT_TO_GND_BIT)
faults.add("Short To GND");
if ((f & MAX31855.FAULT_SHORT_TO_VCC_BIT) == MAX31855.FAULT_SHORT_TO_VCC_BIT)
faults.add("Short To VCC");
boolean first = true;
String text = "Faults = ";
for (String fault : faults) {
if (!first)
text += ", ";
text += fault;
}
if (faults.size() > 0) {
faultTime = System.nanoTime();
}
updateTextView(faultsText, text);
}
});
return new DeviceLooper(max31855);
}
private void updateTextView(final TextView textView, final String text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(text);
}
});
}
/**
* This is the thread on which all the IOIO activity happens. It will be run
* every time the application is resumed and aborted when it is paused. The
* method setup() will be called right after a connection with the IOIO has
* been established (which might happen several times!). Then, loop() will
* be called repetitively until the IOIO gets disconnected.
*/
class DeviceLooper extends BaseIOIOLooper {
private IOIOLooper device;
public DeviceLooper(IOIOLooper device) {
this.device = device;
}
#Override
public void setup() throws ConnectionLostException, InterruptedException {
device.setup(ioio_);
updateTextView(ioioStatusText, "IOIO Connected");
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
device.loop();
}
#Override
public void disconnected() {
device.disconnected();
updateTextView(ioioStatusText, "IOIO Disconnected");
}
#Override
public void incompatible() {
updateTextView(ioioStatusText, "IOIO Incompatible");
}
}
}
I hope this makes sense and I have provided enough information. There is another separate activity for the MAX31855, but I assume this can be left untouched. Again, I am slowly learning how java and android studio works, I just can't seem to figure out how to merge these two activities without having a bunch of errors in the code. Any help is appreciated, thank you!
You need to consider three things.
1) main.xml Layout file in res->layout
2) AndroidManifest.xml in manifest folder
3) Single activity which include all codes.
All components should be initialized from a same activity (in your case MainActivity or IOIOSimpleApp).
Also remember to include all components (what you have initialized from activity) to the main.xml layout.
And try this
public class IOIOSimpleApp extends IOIOActivity {
protected static final float FAULT_DISPLAY_DURATION = 10; // seconds
private TextView boost;
private TextView fuelpressure;
private TextView ioioStatusText;
private TextView internalText;
private TextView thermocoupleText;
private TextView faultsText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
//components in main activity
ioioStatusText = (TextView) findViewById(R.id.ioio_status);
internalText = (TextView) findViewById(R.id.internal);
thermocoupleText = (TextView) findViewById(R.id.thermocouple);
faultsText = (TextView) findViewById(R.id.faults);
boost = (TextView) findViewById(R.id.boost);
fuelpressure = (TextView) findViewById(R.id.fuelpressure);
enableUi(false);
}
class Looper extends BaseIOIOLooper {
private AnalogInput boost, fuelpressure;
#Override
public void setup() throws ConnectionLostException {
boost = ioio_.openAnalogInput(45);
fuelpressure = ioio_.openAnalogInput(42);
enableUi(true);
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
setNumber1(38.314 * ((boost.getVoltage() - 0.27)));
setNumber2(38.314 * ((fuelpressure.getVoltage() - 0.27)));
Thread.sleep(200);
}
#Override
public void disconnected() {
enableUi(false);
}
}
#Override
protected IOIOLooper createIOIOLooper() {
int sdoPin = 1; // DO
int sdaPin = 29; // we do not use this pin but the IOIOLib requires we specify it, so we pick an unused pin
int sclPin = 2; // CLK
int csPin = 3; // CS
SpiMaster.Rate rate = SpiMaster.Rate.RATE_31K;
final MAX31855 max31855 = new MAX31855(sdoPin, sdaPin, sclPin, csPin, rate);
max31855.setListener(new MAX31855.MAX31855Listener() {
private long faultTime;
#Override
public void onData(float internal, float thermocouple) {
updateTextView(internalText, "Internal = " + internal + " C");
updateTextView(thermocoupleText, thermocouple + " C");
float secondsSinceFault = (System.nanoTime() - faultTime) / 1000000000.0f;
if (secondsSinceFault > FAULT_DISPLAY_DURATION) {
updateTextView(faultsText, "Faults = ");
}
}
#Override
public void onFault(byte f) {
List<String> faults = new ArrayList<String>();
if ((f & MAX31855.FAULT_OPEN_CIRCUIT_BIT) == MAX31855.FAULT_OPEN_CIRCUIT_BIT)
faults.add("Open Circuit");
if ((f & MAX31855.FAULT_SHORT_TO_GND_BIT) == MAX31855.FAULT_SHORT_TO_GND_BIT)
faults.add("Short To GND");
if ((f & MAX31855.FAULT_SHORT_TO_VCC_BIT) == MAX31855.FAULT_SHORT_TO_VCC_BIT)
faults.add("Short To VCC");
boolean first = true;
String text = "Faults = ";
for (String fault : faults) {
if (!first)
text += ", ";
text += fault;
}
if (faults.size() > 0) {
faultTime = System.nanoTime();
}
updateTextView(faultsText, text);
}
});
return new IOIOSimpleApp.DeviceLooper(max31855);
}
private void enableUi(final boolean enable) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//seekBar_.setEnabled(enable);
//toggleButton_.setEnabled(enable);
}
});
}
private void setNumber1(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
boost.setText(str);
}
});
}
private void setNumber2(double f) {
final String str = String.format("%.0f", f);
runOnUiThread(new Runnable() {
#Override
public void run() {
fuelpressure.setText(str);
}
});
}
private void updateTextView(final TextView textView, final String text) {
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(text);
}
});
}
/**
* This is the thread on which all the IOIO activity happens. It will be run
* every time the application is resumed and aborted when it is paused. The
* method setup() will be called right after a connection with the IOIO has
* been established (which might happen several times!). Then, loop() will
* be called repetitively until the IOIO gets disconnected.
*/
class DeviceLooper extends BaseIOIOLooper {
private IOIOLooper device;
public DeviceLooper(IOIOLooper device) {
this.device = device;
}
#Override
public void setup() throws ConnectionLostException, InterruptedException {
device.setup(ioio_);
updateTextView(ioioStatusText, "IOIO Connected");
}
#Override
public void loop() throws ConnectionLostException, InterruptedException {
device.loop();
}
#Override
public void disconnected() {
device.disconnected();
updateTextView(ioioStatusText, "IOIO Disconnected");
}
#Override
public void incompatible() {
updateTextView(ioioStatusText, "IOIO Incompatible");
}
} }
Hope this is work :)
Related
Pls, I'm having problems having a steady connection between my android app and my smartwatch, anytime the app connect with the watch, it connect and disconnect immediately. I actually use a custom crrp sdk for the project
This is the scan activity
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.crrepa.ble.CRPBleClient;
import com.crrepa.ble.conn.CRPBleDevice;
import com.crrepa.ble.conn.listener.CRPBleFirmwareUpgradeListener;
import com.crrepa.ble.scan.bean.CRPScanDevice;
import com.crrepa.ble.scan.callback.CRPScanCallback;
import com.crrepa.ble.trans.upgrade.bean.HSFirmwareInfo;
import com.crrepa.sdk.sample.PermissionUtils;
import com.crrepa.sdk.sample.R;
import com.crrepa.sdk.sample.SampleApplication;
import com.crrepa.sdk.sample.device.DeviceActivity;
import java.io.File;
import java.util.List;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class ScanActivity extends AppCompatActivity {
private static final String TAG = "ScanActivity";
private static final int SCAN_PERIOD = 10 * 1000;
private static final int REQUEST_UPDATEBANDCONFIG = 4;
private static final String[] PERMISSION_UPDATEBANDCONFIG = new String[] {
"android.permission.WRITE_EXTERNAL_STORAGE",
"android.permission.READ_EXTERNAL_STORAGE",
"android.permission.ACCESS_FINE_LOCATION",
"android.permission.ACCESS_COARSE_LOCATION"};
#BindView(R.id.btn_scan_toggle)
Button scanToggleBtn;
#BindView(R.id.scan_results)
RecyclerView scanResults;
#BindView(R.id.tv_firmware_fix_state)
TextView tvFirmwareFixState;
private CRPBleClient mBleClient;
private ScanResultsAdapter mResultsAdapter;
private boolean mScanState = false;
private static final String UPGRADE_APP_FILE_PATH = Environment.getExternalStorageDirectory().getPath()
+ File.separator + "crrepa" + File.separator + "app_band-hs.bin";
private static final String UPGRADE_USER_FILE_PATH = Environment.getExternalStorageDirectory().getPath()
+ File.separator + "crrepa" + File.separator + "usr.bin";
private static final String USER_START_ADDRESS = "23000";
// private static final String BAND_ADDRESS = "C1:C4:7C:DE:44:5B";
// private static final String BAND_ADDRESS = "D9:4D:C2:BB:F3:F4";
private static final String BAND_ADDRESS = "FB:09:C5:C7:1A:90";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scan);
ButterKnife.bind(this);
mBleClient = SampleApplication.getBleClient(this);
configureResultList();
requestPermissions();
}
#Override
protected void onPause() {
super.onPause();
cancelScan();
}
#OnClick({R.id.btn_scan_toggle, R.id.btn_firmware_fix, R.id.btn_hs_upgrade})
public void onViewClicked(View view) {
if (!mBleClient.isBluetoothEnable()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivity(enableBtIntent);
return;
}
switch (view.getId()) {
case R.id.btn_scan_toggle:
if (mScanState) {
cancelScan();
} else {
startScan();
}
break;
case R.id.btn_firmware_fix:
break;
case R.id.btn_hs_upgrade:
CRPBleClient bleClient = SampleApplication.getBleClient(this);
CRPBleDevice bleDevice = bleClient.getBleDevice(BAND_ADDRESS);
HSFirmwareInfo upgradeInfo = new HSFirmwareInfo();
upgradeInfo.setAppFilePath(UPGRADE_APP_FILE_PATH);
upgradeInfo.setUserFilePath(UPGRADE_USER_FILE_PATH);
upgradeInfo.setUserStartAddress(USER_START_ADDRESS);
break;
}
}
private void startScan() {
boolean success = mBleClient.scanDevice(new CRPScanCallback() {
#Override
public void onScanning(final CRPScanDevice device) {
Log.d(TAG, "address: " + device.getDevice().getAddress());
if (TextUtils.isEmpty(device.getDevice().getName())) {
return;
}
runOnUiThread(new Runnable() {
#Override
public void run() {
mResultsAdapter.addScanResult(device);
}
});
}
#Override
public void onScanComplete(List<CRPScanDevice> results) {
if (mScanState) {
mScanState = false;
updateButtonUIState();
}
}
}, SCAN_PERIOD);
if (success) {
mScanState = true;
updateButtonUIState();
mResultsAdapter.clearScanResults();
}
}
private void cancelScan() {
mBleClient.cancelScan();
}
private void configureResultList() {
scanResults.setHasFixedSize(true);
LinearLayoutManager recyclerLayoutManager = new LinearLayoutManager(this);
scanResults.setLayoutManager(recyclerLayoutManager);
mResultsAdapter = new ScanResultsAdapter();
scanResults.setAdapter(mResultsAdapter);
mResultsAdapter.setOnAdapterItemClickListener(new ScanResultsAdapter.OnAdapterItemClickListener() {
#Override
public void onAdapterViewClick(View view) {
final int childAdapterPosition = scanResults.getChildAdapterPosition(view);
final CRPScanDevice itemAtPosition = mResultsAdapter.getItemAtPosition(childAdapterPosition);
onAdapterItemClick(itemAtPosition);
}
});
}
private void onAdapterItemClick(CRPScanDevice scanResults) {
final String macAddress = scanResults.getDevice().getAddress();
mBleClient.cancelScan();
final Intent intent = new Intent(this, DeviceActivity.class);
intent.putExtra(DeviceActivity.DEVICE_MACADDR, macAddress);
startActivity(intent);
}
private void updateButtonUIState() {
scanToggleBtn.setText(mScanState ? R.string.stop_scan : R.string.start_scan);
}
CRPBleFirmwareUpgradeListener mFirmwareUpgradeListener = new CRPBleFirmwareUpgradeListener() {
#Override
public void onFirmwareDownloadStarting() {
Log.d(TAG, "onFirmwareDownloadStarting");
updateTextView(tvFirmwareFixState, getString(R.string.dfu_status_download_starting));
}
#Override
public void onFirmwareDownloadComplete() {
Log.d(TAG, "onFirmwareDownloadComplete");
updateTextView(tvFirmwareFixState, getString(R.string.dfu_status_download_complete));
}
#Override
public void onUpgradeProgressStarting() {
Log.d(TAG, "onUpgradeProgressStarting");
updateTextView(tvFirmwareFixState, getString(R.string.dfu_status_starting));
}
#Override
public void onUpgradeProgressChanged(int percent, float speed) {
Log.d(TAG, "onUpgradeProgressChanged: " + percent);
String status = String.format(getString(R.string.dfu_status_uploading_part), percent);
updateTextView(tvFirmwareFixState, status);
}
#Override
public void onUpgradeCompleted() {
Log.d(TAG, "onUpgradeCompleted");
updateTextView(tvFirmwareFixState, getString(R.string.dfu_status_completed));
}
#Override
public void onUpgradeAborted() {
Log.d(TAG, "onUpgradeAborted");
updateTextView(tvFirmwareFixState, getString(R.string.dfu_status_aborted));
}
#Override
public void onError(int errorType, String message) {
Log.d(TAG, "onError: " + errorType);
updateTextView(tvFirmwareFixState, message);
}
};
void updateTextView(final TextView view, final String con) {
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setText(con);
}
});
}
void requestPermissions() {
if (!PermissionUtils.hasSelfPermissions(this, PERMISSION_UPDATEBANDCONFIG)) {
ActivityCompat.requestPermissions(
this, PERMISSION_UPDATEBANDCONFIG, REQUEST_UPDATEBANDCONFIG);
}
}
}
and the device activity here where data is transferred between the watch and the app
private static final String TAG = "DeviceActivity";
public static final String DEVICE_MACADDR = "device_macaddr";
private static final String UI_FILE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + "crrepa" + File.separator + "ota" + File.separator
+ "eaf49ccb4dbe5df51af35803662867d5.bin";
ProgressDialog mProgressDialog;
CRPBleClient mBleClient;
CRPBleDevice mBleDevice;
CRPBleConnection mBleConnection;
boolean isUpgrade = false;
#BindView(R.id.tv_connect_state)
TextView tvConnectState;
#BindView(R.id.tv_firmware_version)
TextView tvFirmwareVersion;
#BindView(R.id.tv_battery)
TextView tvBattery;
#BindView(R.id.tv_step)
TextView tvStep;
#BindView(R.id.tv_distance)
TextView tvDistance;
#BindView(R.id.tv_calorie)
TextView tvCalorie;
#BindView(R.id.tv_restful)
TextView tvRestful;
#BindView(R.id.tv_light)
TextView tvLight;
#BindView(R.id.tv_heart_rate)
TextView tvHeartRate;
#BindView(R.id.tv_blood_pressure)
TextView tvBloodPressure;
#BindView(R.id.tv_upgrade_state)
TextView tvUpgradeState;
#BindView(R.id.btn_ble_connect_state)
Button btnBleDisconnect;
#BindView(R.id.tv_blood_oxygen)
TextView tvBloodOxygen;
#BindView(R.id.tv_new_firmware_version)
TextView tvNewFirmwareVersion;
private String bandFirmwareVersion;
private List<Integer> supportWatchFaceList;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_device);
ButterKnife.bind(this);
initView();
mProgressDialog = new ProgressDialog(this);
String macAddr = getIntent().getStringExtra(DEVICE_MACADDR);
//BluetoothDevice device = BluetoothAdapter.
if (TextUtils.isEmpty(macAddr)) {
finish();
return;
}
mBleClient = SampleApplication.getBleClient(this);
mBleDevice = mBleClient.getBleDevice(macAddr);
if (mBleDevice != null && !mBleDevice.isConnected()) {
connect();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mBleDevice != null) {
mBleDevice.disconnect();
}
}
void initView() {
updateStepInfo(0, 0, 0);
updateSleepInfo(0, 0);
}
void connect() {
mProgressDialog.show();
mBleDevice.connect();
mBleConnection = mBleDevice.connect();
mBleConnection.setConnectionStateListener(new CRPBleConnectionStateListener() {
#Override
public void onConnectionStateChange(int newState) {
Log.d(TAG, "onConnectionStateChange: " + newState);
int state = -1;
switch (newState) {
case CRPBleConnectionStateListener.STATE_CONNECTED:
DeviceActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// state = R.string.state_connected;
mProgressDialog.dismiss();
updateTextView(btnBleDisconnect, getString(R.string.disconnect));
Toast.makeText(DeviceActivity.this, "connected", Toast.LENGTH_SHORT).show();
}
});
testSet();
break;
case CRPBleConnectionStateListener.STATE_CONNECTING:
state = R.string.state_connecting;
break;
case CRPBleConnectionStateListener.STATE_DISCONNECTED:
//closeGatt();
state = R.string.state_disconnected;
mProgressDialog.dismiss();
updateTextView(btnBleDisconnect, getString(R.string.connect));
break;
}
updateConnectState(state);
}
});
mBleConnection.setStepChangeListener(mStepChangeListener);
mBleConnection.setSleepChangeListener(mSleepChangeListener);
mBleConnection.setHeartRateChangeListener(mHeartRateChangListener);
mBleConnection.setBloodPressureChangeListener(mBloodPressureChangeListener);
mBleConnection.setBloodOxygenChangeListener(mBloodOxygenChangeListener);
mBleConnection.setFindPhoneListener(mFindPhoneListener);
mBleConnection.setECGChangeListener(mECGChangeListener, CRPEcgMeasureType.TI);
mBleConnection.setStepsCategoryListener(mStepsCategoryChangeListener);
mBleConnection.setSleepActionChangeListener(mSleepActionChangeListener);
mBleConnection.setMovementStateListener(mMovementStateListener);
mBleConnection.setTempChangeListener(mTempChangeListener);
mBleConnection.setContactListener(mContactListener);
mBleConnection.setHrvChangeListener(mHrvChangeListener);
}
private void closeGatt() {
if (mBleConnection != null) {
mBleConnection.close();
}
}```
I want that after click to TextView show animation after that (after animation) show some modal window. How I may do this? P.s. My animation contained in XML file in <animation-list>
public class ExerciseWithExplain1 extends AppCompatActivity {
private Button solution;
private TextView txtVWRed, explainForTable, solExplain, nextScreen, falseRow53, falseRow54, falseRow55, falseRow56, falseRow46, trueRow45, trueRow44, falseRow43, trueRow36, trueRow35, falseRow34, trueRow33, trueRow23, falseRow23, trueRow25, trueRow24, falseRow24, falseRow25, falseRow26, falseRow33, trueRow34, falseRow35, falseRow36, trueRow43, falseRow44, falseRow45, trueRow46, trueRow53, trueRow54, trueRow55, trueRow56, trueRow26;
LinearLayout layForTable;
AlertDialog.Builder ad;
Context context;
AnimationDrawable animationDrawable;
ImageView animImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exercise_with_explain1);
trueRow23 = findViewById(R.id.trueRow23);
falseRow23 = findViewById(R.id.falseRow23);
falseRow24 = findViewById(R.id.falseRow24);
trueRow24 = findViewById(R.id.trueRow24);
trueRow25 = findViewById(R.id.trueRow25);
falseRow25 = findViewById(R.id.falseRow25);
trueRow26 = findViewById(R.id.trueRow26);
falseRow26 = findViewById(R.id.falseRow26);
falseRow33 = findViewById(R.id.falseRow33);
trueRow33 = findViewById(R.id.trueRow33);
trueRow34 = findViewById(R.id.trueRow34);
falseRow34 = findViewById(R.id.falseRow34);
falseRow35 = findViewById(R.id.falseRow35);
trueRow35 = findViewById(R.id.trueRow35);
falseRow36 = findViewById(R.id.falseRow36);
trueRow36 = findViewById(R.id.trueRow36);
trueRow43 = findViewById(R.id.trueRow43);
falseRow44 = findViewById(R.id.falseRow44);
falseRow45 = findViewById(R.id.falseRow45);
falseRow43 = findViewById(R.id.falseRow43);
trueRow44 = findViewById(R.id.trueRow44);
trueRow45 = findViewById(R.id.trueRow45);
trueRow46 = findViewById(R.id.trueRow46);
falseRow46 = findViewById(R.id.falseRow46);
trueRow53 = findViewById(R.id.trueRow53);
trueRow54 = findViewById(R.id.trueRow54);
trueRow55 = findViewById(R.id.trueRow55);
trueRow56 =findViewById(R.id.trueRow56);
falseRow53 = findViewById(R.id.falseRow53);
falseRow54 = findViewById(R.id.falseRow54);
falseRow55 = findViewById(R.id.falseRow55);
falseRow56 =findViewById(R.id.falseRow56);
animImage = findViewById(R.id.animImage);
animImage.setBackgroundResource(R.drawable.question_mark);
animationDrawable = (AnimationDrawable) animImage.getBackground();
context = ExerciseWithExplain1.this;
ad = new AlertDialog.Builder(context);
ad.setTitle(R.string.explainLogic);
ad.setMessage(R.string.logicForAnd);
final int ir = 0;
falseRow56.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animImage.setVisibility(View.VISIBLE);
animationDrawable.start();
ad.show();
}
});
trueRow56.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animImage.setVisibility(View.VISIBLE);
animationDrawable.start();
}
});
falseRow55.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animImage.setVisibility(View.VISIBLE);
animationDrawable.start();
}
});
You can Try it by using Custom AnimationDrwable
import android.graphics.drawable.AnimationDrawable;
import android.os.Handler;
public abstract class CustomAnimationDrawableNew extends AnimationDrawable {
/** Handles the animation callback. */
Handler mAnimationHandler;
public CustomAnimationDrawableNew(AnimationDrawable aniDrawable) {
/* Add each frame to our animation drawable */
for (int i = 0; i < aniDrawable.getNumberOfFrames(); i++) {
this.addFrame(aniDrawable.getFrame(i), aniDrawable.getDuration(i));
}
}
#Override
public void start() {
super.start();
/*
* Call super.start() to call the base class start animation method.
* Then add a handler to call onAnimationFinish() when the total
* duration for the animation has passed
*/
mAnimationHandler = new Handler();
mAnimationHandler.post(new Runnable() {
#Override
public void run() {
onAnimationStart();
}
});
mAnimationHandler.postDelayed(new Runnable() {
#Override
public void run() {
onAnimationFinish();
}
}, getTotalDuration());
}
/**
* Gets the total duration of all frames.
*
* #return The total duration.
*/
public int getTotalDuration() {
int iDuration = 0;
for (int i = 0; i < this.getNumberOfFrames(); i++) {
iDuration += this.getDuration(i);
}
return iDuration;
}
/**
* Called when the animation finishes.
*/
public abstract void onAnimationFinish();
/**
* Called when the animation starts.
*/
public abstract void onAnimationStart();
}
Now Use it like this code.
TextView tv = (TextView) findViewById(R.id.iv_testing_testani);
tv.setOnClickListener(new OnClickListener() {
public void onClick(final View v) {
// Pass our animation drawable to our custom drawable class
CustomAnimationDrawableNew cad = new CustomAnimationDrawableNew(
(AnimationDrawable) getResources().getDrawable(
R.drawable.anim_test)) {
#Override
void onAnimationStart() {
// Animation has started...
}
#Override
void onAnimationFinish() {
// Animation has finished...
}
};
// Set the views drawable to our custom drawable
v.setBackgroundDrawable(cad);
// Start the animation
cad.start();
}
});
Yesterday i ask a simplified question of my problem, but think its too simplified.
What my programm should do, is to hear a keyword and when he hear it, he should listen to what i said. (like if you told to siri or google now, by saying siri or ok google).
I'm using pocketsphinx for the keyword and the google speechrecognizer for the longer parts. It works, but only for one time. The pocketsphinx is in the MainActivity and the google recognizer is in an extra class (Jarvis).
The programm starts with the pocketsphinx listener, when he hear the KEYPHRASE, he starts the google listener by calling jarvis.startListener() (by the next()-method) and there is the problem, when the googlelistener is done, i dont come back from the Jarvis-class to the MainActivity to call the next() method again.
(when the google recognizer is done, the last things he do is in the onResult() in Jarvis-class, but from there i cant call the next()-method from MainActivity-class)
MainActivity
package com.example.superuser.jarvis;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import edu.cmu.pocketsphinx.Assets;
import edu.cmu.pocketsphinx.Hypothesis;
import edu.cmu.pocketsphinx.SpeechRecognizer;
import edu.cmu.pocketsphinx.SpeechRecognizerSetup;
import static android.widget.Toast.makeText;
import static edu.cmu.pocketsphinx.SpeechRecognizerSetup.defaultSetup;
public class MainActivity extends Activity implements edu.cmu.pocketsphinx.RecognitionListener {
private String LOG_TAG = "Jarvis_hears_anything";
private TextView tv;
private Jarvis jarvis;
private boolean wannahearjarvis = false;
/* Named searches allow to quickly reconfigure the decoder */
private static final String KWS_SEARCH = "wakeup";
/* Keyword we are looking for to activate menu */
private static final String KEYPHRASE = "jarvis";
private edu.cmu.pocketsphinx.SpeechRecognizer recognizer;
//private HashMap<String, Integer> captions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.b1);
tv = (TextView) findViewById(R.id.tv1);
//captions = new HashMap<String, Integer>();
//captions.put(KWS_SEARCH, R.string.kws_caption);
jarvis = new Jarvis(getApplicationContext());
new AsyncTask<Void, Void, Exception>() {
#Override
protected Exception doInBackground(Void... params) {
try {
Assets assets = new Assets(MainActivity.this);
File assetDir = assets.syncAssets();
setupRecognizer(assetDir);
} catch (IOException e) {
return e;
}
return null;
}
#Override
protected void onPostExecute(Exception result) {
if (result != null) {
((TextView) findViewById(R.id.tv1))
.setText("Failed to init recognizer " + result);
} else {
//switchSearch(KWS_SEARCH);
recognizer.startListening(KWS_SEARCH);
}
}
}.execute();
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "geht", Toast.LENGTH_SHORT).show();
}
});
}
public void next(){
if (wannahearjarvis){
recognizer.startListening(KWS_SEARCH);
wannahearjarvis = false;
}
else{
jarvis.startListening();
wannahearjarvis = true;
}
}
#Override
public void onDestroy() {
super.onDestroy();
recognizer.cancel();
recognizer.shutdown();
}
/**
* In partial result we get quick updates about current hypothesis. In
* keyword spotting mode we can react here, in other modes we need to wait
* for final result in onResult.
*/
#Override
public void onPartialResult(Hypothesis hypothesis) {
if (hypothesis == null)
return;
String text = hypothesis.getHypstr();
if (text.equals(KEYPHRASE)){
tv.append("found");
recognizer.stop();
//switchSearch(KWS_SEARCH);
}
else {
//((TextView) findViewById(R.id.tv1)).append(text+"PR");
//Log.i(LOG_TAG, text+"PR");
}
}
/**
* This callback is called when we stop the recognizer.
*/
#Override
public void onResult(Hypothesis hypothesis) {
//((TextView) findViewById(R.id.tv1)).setText("");
((TextView) findViewById(R.id.tv1)).append("oR");
if (hypothesis != null) {
String text = hypothesis.getHypstr();
makeText(getApplicationContext(), text, Toast.LENGTH_SHORT).show();
}
next();
}
#Override
public void onBeginningOfSpeech() {
}
/**
* We stop recognizer here to get a final result
*/
#Override
public void onEndOfSpeech() {
if (!recognizer.getSearchName().equals(KWS_SEARCH)){
tv.append("fuck");
}
//switchSearch(KWS_SEARCH);
}
/*private void switchSearch(String searchName) {
recognizer.stop();
// If we are not spotting, start listening with timeout (10000 ms or 10 seconds).
if (searchName.equals(KWS_SEARCH))
recognizer.startListening(searchName);
else
recognizer.startListening(searchName, 10000);
//String caption = getResources().getString(captions.get(searchName));
//((TextView) findViewById(R.id.tv1)).setText(caption);
//((TextView) findViewById(R.id.tv1)).append(caption);
}*/
private void setupRecognizer(File assetsDir) throws IOException {
// The recognizer can be configured to perform multiple searches
// of different kind and switch between them
recognizer = defaultSetup()
.setAcousticModel(new File(assetsDir, "en-us-ptm"))
.setDictionary(new File(assetsDir, "cmudict-en-us.dict"))
// To disable logging of raw audio comment out this call (takes a lot of space on the device)
.setRawLogDir(assetsDir)
// Threshold to tune for keyphrase to balance between false alarms and misses
.setKeywordThreshold(1e-20f)
// Use context-independent phonetic search, context-dependent is too slow for mobile
.setBoolean("-allphone_ci", true)
.getRecognizer();
recognizer.addListener(this);
/** In your application you might not need to add all those searches.
* They are added here for demonstration. You can leave just one.
*/
// Create keyword-activation search.
recognizer.addKeyphraseSearch(KWS_SEARCH, KEYPHRASE);
}
#Override
public void onError(Exception error) {
((TextView) findViewById(R.id.tv1)).setText(error.getMessage());
}
#Override
public void onTimeout() {
//switchSearch(KWS_SEARCH);
}
}
Jarvis
package com.example.superuser.jarvis;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.speech.RecognitionListener;
import android.speech.RecognizerIntent;
import android.speech.SpeechRecognizer;
import android.widget.Toast;
import java.util.ArrayList;
public class Jarvis implements RecognitionListener{
private AudioManager audiom;
private SpeechRecognizer speech;
private Intent recogIntent;
private Toast m;
private Context c;
private String text;
public Jarvis(Context context){
speech = SpeechRecognizer.createSpeechRecognizer(context);
speech.setRecognitionListener(this);
recogIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
recogIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_PREFERENCE, "de");
//recogIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, context.getPackageName());
m = new Toast(context);
c=context;
}
public void startListening(){
speech.startListening(recogIntent);
}
public void destroy(){
speech.stopListening();
speech.cancel();
speech.destroy();
}
#Override
public void onReadyForSpeech(Bundle params) {
}
#Override
public void onBeginningOfSpeech() {
}
#Override
public void onRmsChanged(float rmsdB) {
}
#Override
public void onBufferReceived(byte[] buffer) {
}
#Override
public void onEndOfSpeech() {
}
#Override
public void onError(int error) {
}
#Override
public void onResults(Bundle results) {
ArrayList<String> matches = results
.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
Toast.makeText(c, matches.get(0), Toast.LENGTH_LONG).show();
speech.cancel();
//tried
//MainActivity m = new MainActivity();
//m.next();
//but got a Nullpointer Exception
}
#Override
public void onPartialResults(Bundle partialResults) {
}
#Override
public void onEvent(int eventType, Bundle params) {
}
}
You can store reference to the main activity in Jarvis object in a field:
class Jarvis {
....
private MainActivity m;
....
public Jarvis(MainActivity m) {
this.m = m;
}
....
public void onResults(Bundle results) {
....
m.next();
}
You can also send intents to the main activity as described here. This might be overkill in your case though.
i'm using youtubeApi (https://developers.google.com/youtube/android/player/downloads/), I'm looking for a solution for put an onclick listener on the videos on the VideoWall..
package com.android.youbho.Activities;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import com.google.android.youtube.player.YouTubeInitializationResult;
import com.google.android.youtube.player.YouTubePlayer;
import com.google.android.youtube.player.YouTubePlayer.PlayerStyle;
import com.google.android.youtube.player.YouTubePlayerFragment;
import com.google.android.youtube.player.YouTubeThumbnailLoader;
import com.google.android.youtube.player.YouTubeThumbnailView;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.Toast;
import com.android.youbho.Utils.Constant;
import com.android.youbho.Utils.FlippingView;
import com.android.youbho.Utils.ImageWallView;
#SuppressLint("NewApi") public class VideoWallActivity extends Activity implements
FlippingView.Listener,
YouTubePlayer.OnInitializedListener,
YouTubeThumbnailView.OnInitializedListener{
private static final int RECOVERY_DIALOG_REQUEST = 1;
/** The player view cannot be smaller than 110 pixels high. */
private static final float PLAYER_VIEW_MINIMUM_HEIGHT_DP = 110;
private static final int MAX_NUMBER_OF_ROWS_WANTED = 4;
// Example playlist from which videos are displayed on the video wall
private static final String PLAYLIST_ID = "PLBA95EAD360E2B0D1";
private static final int INTER_IMAGE_PADDING_DP = 5;
// YouTube thumbnails have a 16 / 9 aspect ratio
private static final double THUMBNAIL_ASPECT_RATIO = 16 / 9d;
private static final int INITIAL_FLIP_DURATION_MILLIS = 100;
private static final int FLIP_DURATION_MILLIS = 500;
private static final int FLIP_PERIOD_MILLIS = 2000;
private ImageWallView imageWallView;
private Handler flipDelayHandler;
private FlippingView flippingView;
private YouTubeThumbnailView thumbnailView;
private YouTubeThumbnailLoader thumbnailLoader;
private YouTubePlayerFragment playerFragment;
private View playerView;
private YouTubePlayer player;
private Dialog errorDialog;
private int flippingCol;
private int flippingRow;
private int videoCol;
private int videoRow;
private boolean nextThumbnailLoaded;
private boolean activityResumed;
private State state;
private static final int id_videoPlayer=99;
private enum State {
UNINITIALIZED,
LOADING_THUMBNAILS,
VIDEO_FLIPPED_OUT,
VIDEO_LOADING,
VIDEO_CUED,
VIDEO_PLAYING,
VIDEO_ENDED,
VIDEO_BEING_FLIPPED_OUT,
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
Toast.makeText(getApplicationContext(), "lol:" + position, Toast.LENGTH_LONG).show();
return view;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #SuppressLint("NewApi") #Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
state = State.UNINITIALIZED;
ViewGroup viewFrame = new FrameLayout(this);
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
int maxAllowedNumberOfRows = (int) Math.floor((displayMetrics.heightPixels / displayMetrics.density) / PLAYER_VIEW_MINIMUM_HEIGHT_DP);
int numberOfRows = Math.min(maxAllowedNumberOfRows, MAX_NUMBER_OF_ROWS_WANTED);
int interImagePaddingPx = (int) displayMetrics.density * INTER_IMAGE_PADDING_DP;
int imageHeight = (displayMetrics.heightPixels / numberOfRows) - interImagePaddingPx;
int imageWidth = (int) (imageHeight * THUMBNAIL_ASPECT_RATIO);
imageWallView = new ImageWallView(this, imageWidth, imageHeight, interImagePaddingPx);
viewFrame.addView(imageWallView, MATCH_PARENT, MATCH_PARENT);
thumbnailView = new YouTubeThumbnailView(this);
thumbnailView.initialize(Constant.DEVELOPER_KEY, this);
flippingView = new FlippingView(this, this, imageWidth, imageHeight);
flippingView.setFlipDuration(INITIAL_FLIP_DURATION_MILLIS);
viewFrame.addView(flippingView, imageWidth, imageHeight);
playerView = new FrameLayout(this);
playerView.setId(id_videoPlayer);
playerView.setVisibility(View.INVISIBLE);
viewFrame.addView(playerView, imageWidth, imageHeight);
playerFragment = YouTubePlayerFragment.newInstance();
playerFragment.initialize(Constant.DEVELOPER_KEY, this);
getFragmentManager().beginTransaction().add(id_videoPlayer, playerFragment).commit();
flipDelayHandler = new FlipDelayHandler();
setContentView(viewFrame);
}
#Override
public void onInitializationSuccess(YouTubeThumbnailView thumbnailView, YouTubeThumbnailLoader thumbnailLoader) {
thumbnailView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "lol! ", Toast.LENGTH_LONG).show();
}
});
this.thumbnailLoader = thumbnailLoader;
thumbnailLoader.setOnThumbnailLoadedListener(new ThumbnailListener());
maybeStartDemo();
}
#Override
public void onInitializationFailure(YouTubeThumbnailView thumbnailView, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
if (errorDialog == null || !errorDialog.isShowing()) {
errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
errorDialog.show();
}
} else {
String errorMessage = String.format( errorReason.toString());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}
#Override
public void onInitializationSuccess(YouTubePlayer.Provider provider, YouTubePlayer player, boolean wasResumed) {
VideoWallActivity.this.player = player;
player.setPlayerStyle(PlayerStyle.CHROMELESS);
player.setPlayerStateChangeListener(new VideoListener());
maybeStartDemo();
}
#Override
public void onInitializationFailure(YouTubePlayer.Provider provider, YouTubeInitializationResult errorReason) {
if (errorReason.isUserRecoverableError()) {
if (errorDialog == null || !errorDialog.isShowing()) {
errorDialog = errorReason.getErrorDialog(this, RECOVERY_DIALOG_REQUEST);
errorDialog.show();
}
} else {
String errorMessage = String.format( errorReason.toString());
Toast.makeText(this, errorMessage, Toast.LENGTH_LONG).show();
}
}
private void maybeStartDemo() {
if (activityResumed && player != null && thumbnailLoader != null && state.equals(State.UNINITIALIZED)) {
thumbnailLoader.setPlaylist(PLAYLIST_ID); // loading the first thumbnail will kick off demo
state = State.LOADING_THUMBNAILS;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RECOVERY_DIALOG_REQUEST) {
// Retry initialization if user performed a recovery action
if (errorDialog != null && errorDialog.isShowing()) {
errorDialog.dismiss();
}
errorDialog = null;
playerFragment.initialize(Constant.DEVELOPER_KEY, this);
thumbnailView.initialize(Constant.DEVELOPER_KEY, this);
}
}
#Override
protected void onResume() {
super.onResume();
activityResumed = true;
if (thumbnailLoader != null && player != null) {
if (state.equals(State.UNINITIALIZED)) {
maybeStartDemo();
} else if (state.equals(State.LOADING_THUMBNAILS)) {
loadNextThumbnail();
} else {
if (state.equals(State.VIDEO_PLAYING)) {
player.play();
}
flipDelayHandler.sendEmptyMessageDelayed(0, FLIP_DURATION_MILLIS);
}
}
}
#Override
protected void onPause() {
flipDelayHandler.removeCallbacksAndMessages(null);
activityResumed = false;
super.onPause();
}
#Override
protected void onDestroy() {
if (thumbnailLoader != null) {
thumbnailLoader.release();
}
super.onDestroy();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) private void flipNext() {
if (!nextThumbnailLoaded || state.equals(State.VIDEO_LOADING)) {
return;
}
if (state.equals(State.VIDEO_ENDED)) {
flippingCol = videoCol;
flippingRow = videoRow;
state = State.VIDEO_BEING_FLIPPED_OUT;
} else {
Pair<Integer, Integer> nextTarget = imageWallView.getNextLoadTarget();
flippingCol = nextTarget.first;
flippingRow = nextTarget.second;
}
flippingView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
flippingView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
flippingView.setFlipInDrawable(thumbnailView.getDrawable());
flippingView.setFlipOutDrawable(imageWallView.getImageDrawable(flippingCol, flippingRow));
imageWallView.setImageDrawable(flippingCol, flippingRow, thumbnailView.getDrawable());
imageWallView.hideImage(flippingCol, flippingRow);
flippingView.setVisibility(View.VISIBLE);
flippingView.flip();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB) #Override
public void onFlipped(FlippingView view) {
imageWallView.showImage(flippingCol, flippingRow);
flippingView.setVisibility(View.INVISIBLE);
if (activityResumed) {
loadNextThumbnail();
if (state.equals(State.VIDEO_BEING_FLIPPED_OUT)) {
state = State.VIDEO_FLIPPED_OUT;
} else if (state.equals(State.VIDEO_CUED)) {
videoCol = flippingCol;
videoRow = flippingRow;
playerView.setX(imageWallView.getXPosition(flippingCol, flippingRow));
playerView.setY(imageWallView.getYPosition(flippingCol, flippingRow));
imageWallView.hideImage(flippingCol, flippingRow);
playerView.setVisibility(View.VISIBLE);
player.play();
state = State.VIDEO_PLAYING;
} else if (state.equals(State.LOADING_THUMBNAILS) && imageWallView.allImagesLoaded()) {
state = State.VIDEO_FLIPPED_OUT; // trigger flip in of an initial video
flippingView.setFlipDuration(FLIP_DURATION_MILLIS);
flipDelayHandler.sendEmptyMessage(0);
}
}
}
private void loadNextThumbnail() {
nextThumbnailLoaded = false;
if (thumbnailLoader.hasNext()) {
thumbnailLoader.next();
} else {
thumbnailLoader.first();
}
}
/**
* A handler that periodically flips an element on the video wall.
*/
#SuppressLint("HandlerLeak")
private final class FlipDelayHandler extends Handler {
#Override
public void handleMessage(Message msg) {
flipNext();
sendEmptyMessageDelayed(0, FLIP_PERIOD_MILLIS);
}
}
/**
* An internal listener which listens to thumbnail loading events from the
* {#link YouTubeThumbnailView}.
*/
private final class ThumbnailListener implements YouTubeThumbnailLoader.OnThumbnailLoadedListener {
#Override
public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
nextThumbnailLoaded = true;
if (activityResumed) {
if (state.equals(State.LOADING_THUMBNAILS)) {
flipNext();
} else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
// load player with the video of the next thumbnail being flipped in
state = State.VIDEO_LOADING;
player.cueVideo(videoId);
}
}
}
#Override
public void onThumbnailError(YouTubeThumbnailView thumbnail, YouTubeThumbnailLoader.ErrorReason reason) {
loadNextThumbnail();
}
}
private final class VideoListener implements YouTubePlayer.PlayerStateChangeListener {
#Override
public void onLoaded(String videoId) {
state = State.VIDEO_CUED;
}
#Override
public void onVideoEnded() {
state = State.VIDEO_ENDED;
imageWallView.showImage(videoCol, videoRow);
playerView.setVisibility(View.INVISIBLE);
}
#Override
public void onError(YouTubePlayer.ErrorReason errorReason) {
if (errorReason == YouTubePlayer.ErrorReason.UNEXPECTED_SERVICE_DISCONNECTION) {
// player has encountered an unrecoverable error - stop the demo
flipDelayHandler.removeCallbacksAndMessages(null);
state = State.UNINITIALIZED;
thumbnailLoader.release();
thumbnailLoader = null;
player = null;
} else {
state = State.VIDEO_ENDED;
}
}
// ignored callbacks
#Override
public void onVideoStarted() { }
#Override
public void onAdStarted() { }
#Override
public void onLoading() { }
}
}
In this way, there are a list of videos in the playlist, each video will start automatically when the first is finished. I need to click each video in the wall for start it
You can add an onClickListener to the ImageViews in the ImageWallView.java class, something like this:
for (int col = 0; col < numberOfColumns; col++) {
for (int row = 0; row < numberOfRows; row++) {
int elementIdx = getElementIdx(col, row);
if (images[elementIdx] == null) {
ImageView thumbnail = new ImageView(context);
thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
images[elementIdx] = thumbnail;
unInitializedImages.add(elementIdx);
thumbnail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
ImageWallView.this.context, (String)v.getTag(), true, false));
}
});
}
addView(images[elementIdx]);
}
}
Then you will need to add the video id as the tag in YouTubeThumbnailView in VideoWallActivity.java
Hope that helps
You can use ImageView OnClickListener as suggested in previous answer: (onSizeChanged in ImageWallView.java)
for (int col = 0; col < numberOfColumns; col++) {
for (int row = 0; row < numberOfRows; row++) {
int elementIdx = getElementIdx(col, row);
if (images[elementIdx] == null) {
ImageView thumbnail = new ImageView(context);
thumbnail.setLayoutParams(new LayoutParams(imageWidth, imageHeight));
images[elementIdx] = thumbnail;
unInitializedImages.add(elementIdx);
thumbnail.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ImageWallView.this.context.startActivity(YouTubeIntents.createPlayVideoIntentWithOptions(
ImageWallView.this.context, (String)v.getTag(), true, false));
}
});
}
addView(images[elementIdx]);
}
}
Then you need to store video id to the calling view of ImageWallView . (set and get tag is also used to store objects between views).
To get the child view of ImageWallView, use imageWallView.getChildAt(index). index is the position of ImageView which is clicked on ImageWallView. to get this index, use getElementIdx(col,row). You need to make this method public in ImageWallView.java.
EDITED
To use the Video ID of current thumbnail, Store the VideoID in onFlipped event. This is because onThumbnailLoaded the VideoID of next thumbnail available which immediately get Flipped and available on IamgeWallView. As VideoID is not available in onFlipped event, use it from onThumbnailLoaded event
Here it is:
Declare below string in class
private String strThumbnailVideoId;
set VideoID in onThumbnailLoaded event (in VideoWallActivity.java) into strThumbnailVideoId. This video ID will be of next thumbnail which will be flipped.
#Override
public void onThumbnailLoaded(YouTubeThumbnailView thumbnail, String videoId) {
nextThumbnailLoaded = true;
strThumbnailVideoId = videoId;
if (activityResumed) {
if (state.equals(State.LOADING_THUMBNAILS)) {
flipNext();
} else if (state.equals(State.VIDEO_FLIPPED_OUT)) {
// load player with the video of the next thumbnail being flipped in
state = State.VIDEO_LOADING;
player.cueVideo(videoId);
}
}
}
Now set the strThumbnailVideoId in onFlipped as a ImageWallView tag.
#Override
public void onFlipped(FlippingView view) {
imageWallView.showImage(flippingCol, flippingRow);
flippingView.setVisibility(View.INVISIBLE);
imageWallView.getChildAt(imageWallView.getElementIdx(flippingCol, flippingRow)).setTag(strThumbnailVideoId);
......
......
What should I do to call thread's pause() method from showExitDialog() here ?
Here's Start Game class
package game.mainmenu;
import game.view.ViewPanel;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.Window;
import android.view.WindowManager;
public class StartGame extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(new ViewPanel(this));
}
#Override
protected void onPause() {
super.onPause();
//saveScores();
this.finish();
System.exit(1);// pause game when Activity pauses
}
#Override
public boolean onKeyDown(final int pKeyCode, final KeyEvent pEvent) {
if (pKeyCode == KeyEvent.KEYCODE_BACK
&& pEvent.getAction() == KeyEvent.ACTION_DOWN) {
showExitDialog();
return true;
}
return super.onKeyDown(pKeyCode, pEvent);
}
public void showExitDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(StartGame.this);
builder.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setTitle("EXIT")
.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
StartGame.this.finish();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
//alert.setIcon(android.R.drawable.star_on);
alert.show();
}
}
Here's class with main thread
public class ViewManager extends Thread
{
//some states here
public static final int STATE_LOSE = 1;
public static final int STATE_PAUSE = 2;
public static final int STATE_READY = 3;
public static final int STATE_RUNNING = 4;
public static final int STATE_WIN = 5;
//..some not mention code here../
public ViewManager(SurfaceHolder surfaceHolder, Context context)
{
mSurfaceHolder = surfaceHolder;
mRunning = false;
mHealthBar = new Rect(0,0,0,0);
mLinePaint = new Paint();
mLinePaint.setAntiAlias(true);
mLinePaint.setARGB(255, 0, 255, 0);
mLinePaint.setTextSize(16);
mLinePaint.setStrokeWidth(3);
mContext = context;
Resources res = context.getResources();
//..some not mention code here../
InitElements(res);
mHero = new PlayerAnimated(mPlayerImage, FIELD_WIDTH/2, 600, 64, 64, 3, 3, context, mEnemiesList);
//mBoom = new Explosion(mExplosionImage, 200, 500, 64, 64, 7, 7);
mEnemyImage = BitmapFactory.decodeResource(res, R.drawable.enemyone);
setState(STATE_RUNNING);
}
/**
* threads state
* #param running
*/
public void setRunning(boolean running)
{
mRunning = running;
}
//..some not mention code here../
public void run()
{
while (mRunning)
{
Canvas canvas = null;
try
{
// подготовка Canvas-а
canvas = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
if(mMode == STATE_RUNNING){
// draw if not paused
addEneimes(mContext);
updateStuff();
doDraw(canvas);
}
else
{
pauseDraw(canvas);
}
ViewPanel.displayFps(canvas, aString);
aString = Integer.toString(hudscore.getScore());
}
}
catch (Exception e) { }
finally
{
if (canvas != null)
{
mSurfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
//..some not mention code here../
public void pause() {
synchronized (mSurfaceHolder) {
setState(STATE_PAUSE);
mLastFiredTime = System.currentTimeMillis() + 100;
}
}
public void unpause() {
//
synchronized (mSurfaceHolder) {
setState(STATE_RUNNING);
mLastFiredTime = System.currentTimeMillis() + 100;
}
}
public void setState(int mode)
{
mMode = mode;
}
public void pauseDraw(Canvas canvas)
{
canvas.drawBitmap(Bitmap.createBitmap(FIELD_WIDTH, FIELD_HEIGHT, Bitmap.Config.RGB_565), 0, 0, null);
}
}
Not really a clear question, since you are not telling us where you want to create and start the Thread in the main code. Let's assume it's inside onCreate:
public class StartGame extends Activity {
private ViewManager viewManager = new ViewManager();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN );
setContentView(new ViewPanel(this));
viewManager.start(); // start viewManager thread
}
// other methods
public void showExitDialog() {
viewManager.pause(); // call pause
// rest of code
}
}