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();
}
});
Related
I am new to Java coding for android. I need to understand why does my code generate 2 threads. The problem that can be created over here is perhaps competition for Camera Resources which results in the camera not being used by the user. Kindly suggest a solution to my problem as well.
I have also attached a picture where there are 2 requests for a new activity. There is also proof by having 2 thread IDs active.
EDIT for clarity:
I want to generate a new thread which solely handles the activity to record the video, no other thread should be doing it. But there are two that are performing their own activity to record video.
public class MainActivity extends AppCompatActivity implements SensorEventListener/*, ActivityCompat.OnRequestPermissionsResultCallback*/ {
private Camera c;
private MainActivity reference_this = this;
private BooleanObject recorded_video = new BooleanObject("recorded_video",false);
private BooleanObject recorded_motions_chest = new BooleanObject("recorded_motions_chest", false);
private ChangeListener listener_change;
public void setListener(ChangeListener arg_listener_change) {
listener_change = arg_listener_change;
}
public interface ChangeListener {
void onChange(String arg_name);
}
public void set_recorded_video(boolean arg_recorded_video) {
recorded_video.set_value(arg_recorded_video);
if (listener_change != null) { listener_change.onChange(recorded_video.get_name()); }
}
public void set_recorded_motions_chest(boolean arg_recorded_motions_chest) {
recorded_motions_chest.set_value(arg_recorded_motions_chest);
if (listener_change != null) { listener_change.onChange(recorded_motions_chest.get_name()); }
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!(getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA))) {
this.finish();
System.exit(0);
}
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
this.setListener(new MainActivity.ChangeListener() {
#Override
public void onChange(String arg_name) {
Log.i("CHNG", "fired");
if (arg_name.equals(recorded_video.get_name())) {
VideoCapture video_capture = new VideoCapture();
video_capture.open(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video_finger.mp4");
Mat frame = new Mat();
int length_video = (int) video_capture.get(Videoio.CAP_PROP_FRAME_COUNT);
int rate_frame = (int) video_capture.get(Videoio.CAP_PROP_FPS);
while (true) {
video_capture.read(frame);
Size size_img = frame.size();
Log.i("MAT", String.valueOf(size_img.width) + ' ' + String.valueOf(size_img.height));
}
}
else if (arg_name.equals(recorded_motions_chest.get_name())) {}
}
});
// new Thread(new Runnable() {
// public void run() {
Button button_symptoms = (Button) findViewById(R.id.button_symptoms);
Button button_upload_signs = (Button) findViewById(R.id.button_upload_signs);
Button button_measure_heart_rate = (Button) findViewById(R.id.button_measure_heart_rate);
Button button_measure_respiratory_rate = (Button) findViewById(R.id.button_measure_respiratory_rate);
CameraView cv1 = new CameraView(getApplicationContext(), reference_this);
FrameLayout view_camera = (FrameLayout) findViewById(R.id.view_camera);
view_camera.addView(cv1);
TextView finger_on_sensor = (TextView) findViewById(R.id.text_finger_on_sensor);
finger_on_sensor.setVisibility(View.INVISIBLE);
finger_on_sensor.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch (View arg_view, MotionEvent arg_me){
finger_on_sensor.setVisibility(View.INVISIBLE);
/*GENERATING THREADS OVER HERE*/ new Thread(new Runnable() {
public void run() {
File file_video = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video_finger.mp4");
// final int REQUEST_WRITE_PERMISSION = 786;
final int VIDEO_CAPTURE = 1;
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent intent_record_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent_record_video.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 45);
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cse535a1.provider", file_video);
intent_record_video.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
if (intent_record_video.resolveActivity(getPackageManager()) != null) {
Log.i("CAM", "CAM requeted");
Log.i("Thread ID", String.valueOf(Thread.currentThread().getId()));
startActivityForResult(intent_record_video, VIDEO_CAPTURE);
// reference_this.set_recorded_video(true);
}
}
}).start();
return true;
}
});
button_symptoms.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View arg_view){
Intent intent = new Intent(getApplicationContext(), Loggin_symptoms.class);
startActivity(intent);
}
});
button_upload_signs.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View arg_view){
}
});
button_measure_heart_rate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick (View arg_view){ finger_on_sensor.setVisibility(View.VISIBLE); }
});
button_measure_respiratory_rate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg_view) {
SensorManager manager_sensor = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor_accelerometer = manager_sensor.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
manager_sensor.registerListener(MainActivity.this, sensor_accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
});
// }}).start();
}
public void setCam(Camera arg_camera) { c = arg_camera; }
#Override
public void onSensorChanged(SensorEvent arg_event) {
float x = arg_event.values[0];
float y = arg_event.values[1];
float z = arg_event.values[2];
Log.i("ACCELEROMETER", String.valueOf(x) + ' ' + String.valueOf(y) + ' ' + String.valueOf(z));
}
#Override
public void onAccuracyChanged(Sensor arg_sensor, int arg_accuracy) {
}
#Override
protected void onPause() {
super.onPause();
c.unlock();
// Log.i("CAM", "unlocked");
// if (c != null) {
// c.stopPreview();
//// c.release();
//// c = null;
// }
}
#Override
protected void onResume() {
super.onResume();
if (c != null) c.lock();
// if (c != null) {
// c.stopPreview();
// c.release();
// c = null;
/// }
// cv1 = new CameraView(getApplicationContext(), this);
// view_camera.addView(cv1);
}
#Override
protected void onDestroy() {
if (c != null) {
// c.unlock();
c.stopPreview();
c.release();
c = null;
}
super.onDestroy();
}
private static class BooleanObject {
private String name = "BooleanObject";
private boolean value = false;
public BooleanObject(String arg_name, boolean arg_value) {
name = arg_name;
value = arg_value;
}
public String set_name(String arg_name) {
name = arg_name;
return name;
}
public boolean set_value(boolean arg_value) {
value = arg_value;
return value;
}
public String get_name() { return name; }
public boolean get_value() { return value; }
};
}
Every time you tap on TextView, as you are using onTouchListener, it will be fired twice, once for ACTION_DOWN and ACTION_UP, so check for ACTION_UP as in
finger_on_sensor.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch (View arg_view, MotionEvent arg_me){
if(arg_me.getAction() == MotionEvent.ACTION_UP){ //add this condition
finger_on_sensor.setVisibility(View.INVISIBLE);
new Thread(new Runnable() {
public void run() {
File file_video = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/video_finger.mp4");
// final int REQUEST_WRITE_PERMISSION = 786;
final int VIDEO_CAPTURE = 1;
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
Intent intent_record_video = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent_record_video.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 45);
Uri fileUri = FileProvider.getUriForFile(MainActivity.this, "com.example.cse535a1.provider", file_video);
intent_record_video.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
if (intent_record_video.resolveActivity(getPackageManager()) != null) {
Log.i("CAM", "CAM requeted");
Log.i("Thread ID", String.valueOf(Thread.currentThread().getId()));
startActivityForResult(intent_record_video, VIDEO_CAPTURE);
//reference_this.set_recorded_video(true);
}
}
}).start();
return true;
}
});
I have 3 AutoCompleteTextView and I want to make a simple function to detect whenever it gain/loses focus so I'll hide an imageView.
Or maybe, whenever the keyboard is UP I want to hide my logo (imageView). When the keyboard is down, show the imageView again.
Code so far:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
RelativeLayout layout = (RelativeLayout)findViewById(R.id.mainLayout);
for(int i=0; i< layout.getChildCount(); i++) {
View v = layout.getChildAt(i);
if(v instanceof AutoCompleteTextView) {
v.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View view, boolean b) {
// if(hasWindowFocus()) {
// ImageView logo = findViewById(R.id.imgLogo);
// logo.setVisibility(View.GONE);
// }
Toast.makeText(getApplicationContext(), "pimba", Toast.LENGTH_LONG).show();
}
});
}
}
}
Also, is it possible to create listeners outside this onCreate() ? Or creating everything inside this function is the right way to go?
Try this
Solution 1
Call this method in onCreate()
private void initKeyBoardListener() {
//Threshold for minimal keyboard height.
final int MIN_KEYBOARD_HEIGHT_PX = 150;
//Top-level window decor view.
final View decorView = getWindow().getDecorView();
// Register global layout listener.
decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
// Retrieve visible rectangle inside window.
private final Rect windowVisibleDisplayFrame = new Rect();
private int lastVisibleDecorViewHeight;
#Override
public void onGlobalLayout() {
decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame);
final int visibleDecorViewHeight = windowVisibleDisplayFrame.height();
if (lastVisibleDecorViewHeight != 0) {
if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
Log.d("Keyboard", "SHOW");
// Hide imageview
} else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
// Show imageview
Log.d("Keyboard", "HIDE");
}
}
// Save current decor view height for the next call.
lastVisibleDecorViewHeight = visibleDecorViewHeight;
}
});
}
Solution 2
Use this Util class
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import java.util.HashMap;
/**
* Created by Raman on 2/10/2017.
*/
public class KeyboardUtils implements ViewTreeObserver.OnGlobalLayoutListener {
private static HashMap<SoftKeyboardToggleListener, KeyboardUtils> sListenerMap = new HashMap<>();
private SoftKeyboardToggleListener mCallback;
private View mRootView;
private float mScreenDensity = 1;
private KeyboardUtils(Activity act, SoftKeyboardToggleListener listener) {
mCallback = listener;
mRootView = ((ViewGroup) act.findViewById(android.R.id.content)).getChildAt(0);
mRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
mScreenDensity = act.getResources().getDisplayMetrics().density;
}
public static void addKeyboardToggleListener(Activity act, SoftKeyboardToggleListener listener) {
removeKeyboardToggleListener(listener);
sListenerMap.put(listener, new KeyboardUtils(act, listener));
}
public static void removeKeyboardToggleListener(SoftKeyboardToggleListener listener) {
if (sListenerMap.containsKey(listener)) {
KeyboardUtils k = sListenerMap.get(listener);
k.removeListener();
sListenerMap.remove(listener);
}
}
public static void removeAllKeyboardToggleListeners() {
for (SoftKeyboardToggleListener l : sListenerMap.keySet())
sListenerMap.get(l).removeListener();
sListenerMap.clear();
}
#Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
mRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = mRootView.getRootView().getHeight() - (r.bottom - r.top);
float dp = heightDiff / mScreenDensity;
if (mCallback != null)
mCallback.onToggleSoftKeyboard(dp > 200);
}
private void removeListener() {
mCallback = null;
mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
public interface SoftKeyboardToggleListener {
void onToggleSoftKeyboard(boolean isVisible);
}
}
And its usage
Call this in onCreate()
KeyboardUtils.addKeyboardToggleListener(getActivity(), new KeyboardUtils.SoftKeyboardToggleListener() {
#Override
public void onToggleSoftKeyboard(boolean isVisible) {
Log.d("keyboard", "keyboard visible: " + isVisible);
if (!isVisible) {
// show imageview
}
else
{
// hide imageview
}
}
});
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 :)
The goal is to implement the following functionality. Three EditText fields. Each of them should be filled with its custom keyboard.
1. English
2. Russian
3. transcription
Keyboards I implemented with the help of this class
public class CustomKeyboard {
/** A link to the KeyboardView that is used to render this CustomKeyboard. */
private KeyboardView mKeyboardView;
/** A link to the activity that hosts the {#link #mKeyboardView}. */
private Activity mHostActivity;
/** The key (code) handler. */
private OnKeyboardActionListener mOnKeyboardActionListener = new OnKeyboardActionListener() {
public final static int CodeDelete = -5; // Keyboard.KEYCODE_DELETE
public final static int CodeCancel = -3; // Keyboard.KEYCODE_CANCEL
public final static int CodePrev = 55000;
public final static int CodeAllLeft = 55001;
public final static int CodeLeft = 55002;
public final static int CodeRight = 55003;
public final static int CodeAllRight = 55004;
public final static int CodeNext = 55005;
public final static int CodeClear = 55006;
#Override public void onKey(int primaryCode, int[] keyCodes) {
// NOTE We can say '<Key android:codes="49,50" ... >' in the xml file; all codes come in keyCodes, the first in this list in primaryCode
// Get the EditText and its Editable
View focusCurrent = mHostActivity.getWindow().getCurrentFocus();
if( focusCurrent==null || focusCurrent.getClass()!=EditText.class ) return;
EditText edittext = (EditText) focusCurrent;
Editable editable = edittext.getText();
int start = edittext.getSelectionStart();
// Apply the key to the edittext
if( primaryCode==CodeCancel ) {
hideCustomKeyboard();
} else if( primaryCode==CodeDelete ) {
if( editable!=null && start>0 ) editable.delete(start - 1, start);
} else if( primaryCode==CodeClear ) {
if( editable!=null ) editable.clear();
} else if( primaryCode==CodeLeft ) {
if( start>0 ) edittext.setSelection(start - 1);
} else if( primaryCode==CodeRight ) {
if (start < edittext.length()) edittext.setSelection(start + 1);
} else if( primaryCode==CodeAllLeft ) {
edittext.setSelection(0);
} else if( primaryCode==CodeAllRight ) {
edittext.setSelection(edittext.length());
} else if( primaryCode==CodePrev ) {
View focusNew= edittext.focusSearch(View.FOCUS_BACKWARD);
if( focusNew!=null ) focusNew.requestFocus();
} else if( primaryCode==CodeNext ) {
View focusNew= edittext.focusSearch(View.FOCUS_FORWARD);
if( focusNew!=null ) focusNew.requestFocus();
} else { // insert character
editable.insert(start, Character.toString((char) primaryCode));
}
}
#Override public void onPress(int arg0) {
}
#Override public void onRelease(int primaryCode) {
}
#Override public void onText(CharSequence text) {
}
#Override public void swipeDown() {
}
#Override public void swipeLeft() {
}
#Override public void swipeRight() {
}
#Override public void swipeUp() {
}
};
/**
* Create a custom keyboard, that uses the KeyboardView (with resource id <var>viewid</var>) of the <var>host</var> activity,
* and load the keyboard layout from xml file <var>layoutid</var> (see {#link Keyboard} for description).
* Note that the <var>host</var> activity must have a <var>KeyboardView</var> in its layout (typically aligned with the bottom of the activity).
* Note that the keyboard layout xml file may include key codes for navigation; see the constants in this class for their values.
* Note that to enable EditText's to use this custom keyboard, call the {#link #registerEditText(int)}.
*
* #param host The hosting activity.
* #param viewid The id of the KeyboardView.
* #param layoutid The id of the xml file containing the keyboard layout.
*/
public CustomKeyboard(Activity host, int viewid, int layoutid) {
mHostActivity= host;
mKeyboardView= (KeyboardView)mHostActivity.findViewById(viewid);
mKeyboardView.setKeyboard(new Keyboard(mHostActivity, layoutid));
mKeyboardView.setPreviewEnabled(false); // NOTE Do not show the preview balloons
mKeyboardView.setOnKeyboardActionListener(mOnKeyboardActionListener);
// Hide the standard keyboard initially
mHostActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
/** Returns whether the CustomKeyboard is visible. */
public boolean isCustomKeyboardVisible() {
return mKeyboardView.getVisibility() == View.VISIBLE;
}
/** Make the CustomKeyboard visible, and hide the system keyboard for view v. */
public void showCustomKeyboard( View v ) {
mKeyboardView.setVisibility(View.VISIBLE);
mKeyboardView.setEnabled(true);
if( v!=null ) ((InputMethodManager)mHostActivity.getSystemService(Activity.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(v.getWindowToken(), 0);
}
/** Make the CustomKeyboard invisible. */
public void hideCustomKeyboard() {
mKeyboardView.setVisibility(View.GONE);
mKeyboardView.setEnabled(false);
}
/**
* Register <var>EditText<var> with resource id <var>resid</var> (on the hosting activity) for using this custom keyboard.
*
* #param resid The resource id of the EditText that registers to the custom keyboard.
*/
public void registerEditText(int resid) {
// Find the EditText 'resid'
//TextInputEditText edittext= (TextInputEditText)mHostActivity.findViewById(resid);
EditText edittext= (EditText)mHostActivity.findViewById(resid);
// Make the custom keyboard appear
edittext.setOnFocusChangeListener(new OnFocusChangeListener() {
// NOTE By setting the on focus listener, we can show the custom keyboard when the edit box gets focus, but also hide it when the edit box loses focus
#Override public void onFocusChange(View v, boolean hasFocus) {
if( hasFocus ) showCustomKeyboard(v); else hideCustomKeyboard();
}
});
edittext.setOnClickListener(new OnClickListener() {
// NOTE By setting the on click listener, we can show the custom keyboard again, by tapping on an edit box that already had focus (but that had the keyboard hidden).
#Override public void onClick(View v) {
showCustomKeyboard(v);
}
});
// Disable standard keyboard hard way
// NOTE There is also an easy way: 'edittext.setInputType(InputType.TYPE_NULL)' (but you will not have a cursor, and no 'edittext.setCursorVisible(true)' doesn't work )
edittext.setOnTouchListener(new OnTouchListener() {
#Override public boolean onTouch(View v, MotionEvent event) {
EditText edittext = (EditText) v;
int inType = edittext.getInputType(); // Backup the input type
edittext.setInputType(InputType.TYPE_NULL); // Disable standard keyboard
edittext.onTouchEvent(event); // Call native handler
edittext.setInputType(inType); // Restore input type
return true; // Consume touch event
}
});
// Disable spell check (hex strings look like words to Android)
edittext.setInputType(edittext.getInputType() | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
}
}
and three different xml-layouts
The Activity I create three copies keyboard class. With different layouts. Register each of them their field.
public class WordsListActivity extends Activity {
public static final String LOG_TAG = "WordsListActivity";
protected RecyclerView mRecyclerView;
protected Button btnAddWord;
protected WordViewAdapter mAdapter;
protected RecyclerView.LayoutManager mLayoutManager;
protected WordsListActivity.LayoutManagerType mCurrentLayoutManagerType;
protected List<Word> wordsList;
protected int categoryId;
protected CustomKeyboard mCustomKeyboardEN, mCustomKeyboardRU, mCustomKeyboardTrancroption;
protected ForegroundLinearLayout addWordLyout;
protected Button okButton, cancelButton;
protected EditText etWordOrigin, etWordTranslate, etWordTranscription;
private enum LayoutManagerType {
GRID_LAYOUT_MANAGER,
LINEAR_LAYOUT_MANAGER
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_words_list);
Intent intent = getIntent();
categoryId = (int) intent.getLongExtra("categoryId",0);
View rootView = getLayoutInflater().inflate(R.layout.content_main, null).getRootView();
mRecyclerView = (RecyclerView)findViewById(R.id.wrodsRecyclerView);
btnAddWord = (Button)findViewById(R.id.btnAddNewWord);
mLayoutManager = new LinearLayoutManager(this);
mCurrentLayoutManagerType = WordsListActivity.LayoutManagerType.LINEAR_LAYOUT_MANAGER;
setRecyclerViewLayoutManager(mCurrentLayoutManagerType);
addWordLyout =(ForegroundLinearLayout)findViewById(R.id.inputWordLayout);
addWordLyout.setVisibility(View.INVISIBLE);
etWordOrigin = (EditText)findViewById(R.id.etWordOrigin);
etWordTranslate = (EditText)findViewById(R.id.etWordTranslate);
etWordTranscription = (EditText)findViewById(R.id.etWordTrancription);
okButton = (Button) findViewById(R.id.addButton);
cancelButton = (Button) findViewById(R.id.cancelButton);
/* creting keybords*/
mCustomKeyboardRU = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_ru);//russian
mCustomKeyboardRU.registerEditText(R.id.etWordOrigin);
mCustomKeyboardEN = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_en);//english
mCustomKeyboardEN.registerEditText(R.id.etWordTranslate);
/*in all EditText field showing this last keyboard copy*/
mCustomKeyboardTrancroption = new CustomKeyboard(this, R.id.keyboardviewWords, R.xml.kbd_transcription);//transcription
mCustomKeyboardTrancroption.registerEditText(R.id.etWordTrancription);
btnAddWord.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addWordLyout.setVisibility(View.VISIBLE);
}
});
}
#Override public void onBackPressed() {
// NOTE Trap the back key: when the CustomKeyboard is still visible hide it, only when it is invisible, finish activity
if( mCustomKeyboardRU.isCustomKeyboardVisible() ) mCustomKeyboardRU.hideCustomKeyboard(); else this.finish();
}
public void setRecyclerViewLayoutManager(WordsListActivity.LayoutManagerType layoutManagerType) {
/*
mLayoutManager = new GridLayoutManager(this, SPAN_COUNT);
mCurrentLayoutManagerType = LayoutManagerType.GRID_LAYOUT_MANAGER;*/
mLayoutManager = new LinearLayoutManager(this);
mCurrentLayoutManagerType = WordsListActivity.LayoutManagerType.LINEAR_LAYOUT_MANAGER;
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.scrollToPosition(0);
initDataset();
}
private void initDataset() {
wordsList = new DataBase(this).getWordsList(categoryId);
mAdapter = new WordViewAdapter(wordsList, this);
mRecyclerView.setAdapter(mAdapter);
if(wordsList.size()==0){
Toast.makeText(this, "nothing to Show", Toast.LENGTH_LONG).show();
}
}
}
but when you run applications with focus on all fields it shows the last keyboard. in this case transcription.
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
}
}