I can see a log in my consolse everytime a beacon is detected
D/BeaconService: beacon detected : id1: xxxxx-xxx-xxxxx-xxx-xxxxx id2: xxx id3: xx
But i could not figure out how to catch this function.
Which interface is needed for get this function.
Thanks
Try this,
// Y positions are relative to height of bg_distance image.
Private static final double RELATIVE_START_POS = 320.0 / 1110.0;
Private static final double RELATIVE_STOP_POS = 885.0 / 1110.0;
Private BeaconManager beaconManager;
Private Beacon beacon;
Private Region region;
Private View distance view, dotView;
Private int startY = -1;
Private int segmentLength = -1;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.distance_view);
dotView = findViewById(R.id.distance_iv_dot);
beacon = getIntent().getParcelableExtra(MainActivity.EXTRAS_BEACON);
region = new Region("regionid", beacon.getProximityUUID(), beacon.getMajor(), beacon.getMinor());
if (beacon == null) {
Toast.makeText(this, "Beacon not found in intent extras", Toast.LENGTH_LONG).show();
finish();
return;
}
beaconManager = new BeaconManager(this);
distanceview = findViewById(R.id.distance_background_view);
distanceview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
distanceview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
startY = (int) (RELATIVE_START_POS * distanceview.getMeasuredHeight());
int stopY = (int) (RELATIVE_STOP_POS * distanceview.getMeasuredHeight());
segmentLength = stopY - startY;
dotView.setVisibility(View.VISIBLE);
dotView.setTranslationY(computeDotPosY(beacon));
}
});
}
private void updateDistanceView(Beacon foundBeacon) {
if (segmentLength == -1) {
return ;
}
dotView.animate().translationY(computeDotPosY(foundBeacon)).start();
}
private int computeDotPosY(Beacon beacon) {
// Let's put dot at the end of the scale when it's further than 6m.
double distance = Math.min(Utils.computeAccuracy(beacon), 6.0);
return startY + (int) (segmentLength * (distance / 6.0));
}
#Override
protected void onStart() {
super.onStart();
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, final List<Beacon> rangedBeacons) {
// Note that results are not delivered on UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// Just in case if there are multiple beacons with the same uuid, major, minor.
Beacon foundBeacon = null;
for (Beacon rangedBeacon : rangedBeacons) {
if (rangedBeacon.getMacAddress().equals(beacon.getMacAddress())) {
foundBeacon = rangedBeacon;
}
}
if (foundBeacon != null) {
updateDistanceView(foundBeacon);
}
}
});
}
});
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
beaconManager.startRanging(region);
}
});
}
#Override
protected void onStop() {
beaconManager.stopRanging(region);
beaconManager.disconnect();
super.onStop();
} }
Write
Translate
Define
Synonyms
Favorites
Personal Trainer
Phrase of the Day
Personal Dictionary
Quick Tour
Tutorials
Settings
Send Feedback
GingerFREE
Public class DistanceBeaconActivity extends AppCompatActivity {
Private static final String TAG = DistanceBeaconActivity. class. getSimpleName ();
// Y positions are relative to height of bg_distance image.
Private static final double RELATIVE_START_POS = 320.0 / 1110.0;
Private static final double RELATIVE_STOP_POS = 885.0 / 1110.0;
Private BeaconManager beaconManager;
Private Beacon beacon;
Private Region region;
Private View distance view, dotView;
Private int startY = -1;
Private int segmentLength = -1;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.distance_view);
dotView = findViewById(R.id.distance_iv_dot);
beacon = getIntent().getParcelableExtra(MainActivity.EXTRAS_BEACON);
region = new Region("regionid", beacon.getProximityUUID(), beacon.getMajor(), beacon.getMinor());
if (beacon == null) {
Toast.makeText(this, "Beacon not found in intent extras", Toast.LENGTH_LONG).show();
finish();
return;
}
beaconManager = new BeaconManager(this);
distanceview = findViewById(R.id.distance_background_view);
distanceview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
distanceview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
startY = (int) (RELATIVE_START_POS * distanceview.getMeasuredHeight());
int stopY = (int) (RELATIVE_STOP_POS * distanceview.getMeasuredHeight());
segmentLength = stopY - startY;
dotView.setVisibility(View.VISIBLE);
dotView.setTranslationY(computeDotPosY(beacon));
}
});
}
private void updateDistanceView(Beacon foundBeacon) {
if (segmentLength == -1) {
return ;
}
dotView.animate().translationY(computeDotPosY(foundBeacon)).start();
}
private int computeDotPosY(Beacon beacon) {
// Let's put dot at the end of the scale when it's further than 6m.
double distance = Math.min(Utils.computeAccuracy(beacon), 6.0);
return startY + (int) (segmentLength * (distance / 6.0));
}
#Override
protected void onStart() {
super.onStart();
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, final List<Beacon> rangedBeacons) {
// Note that results are not delivered on UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// Just in case if there are multiple beacons with the same uuid, major, minor.
Beacon foundBeacon = null;
for (Beacon rangedBeacon : rangedBeacons) {
if (rangedBeacon.getMacAddress().equals(beacon.getMacAddress())) {
foundBeacon = rangedBeacon;
}
}
if (foundBeacon != null) {
updateDistanceView(foundBeacon);
}
}
});
}
});
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
beaconManager.startRanging(region);
}
});
}
#Override
protected void onStop() {
beaconManager.stopRanging(region);
beaconManager.disconnect();
super.onStop();
}
}
I hope it will Help you that to get the function for detecting the Beaconlist.:)
Related
I am making horizontal scrollview gallery, and I want to autoscroll it. Now it's scrolling from left to right but when I reach end of list I just simply jump to first one, but it looks really bad, so I want to go scroll around from beginning avoiding just skipping to first one, or if it is not possible just start scrolling to the other side when I reach last view on right (maybe better option). Could someone help me how to do this?
private LinearLayout horizontalOuterLayout;
private HorizontalScrollView horizontalScrollview;
private int scrollMax;
private int scrollPos = 0;
private TimerTask clickSchedule;
private TimerTask scrollerSchedule;
private TimerTask faceAnimationSchedule;
private Timer scrollTimer = null;
private Timer faceTimer = null;
private String[] imageNameArray ={ "sponsors_czarnykot", "sponsors_estradarzeszow","sponsors_klubp","sponsors_kula","sponsors_czarnykot", "sponsors_estradarzeszow","sponsors_klubp","sponsors_kula" };
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.horizontal_layout);
horizontalScrollview = (HorizontalScrollView) findViewById(R.id.horiztonal_scrollview_id);
horizontalOuterLayout = (LinearLayout) findViewById(R.id.horiztonal_outer_layout_id);
horizontalScrollview.setHorizontalScrollBarEnabled(false);
addImagesToView();
ViewTreeObserver vto = horizontalOuterLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
horizontalOuterLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
getScrollMaxAmount();
startAutoScrolling();
}
});
}
public void getScrollMaxAmount()
{
int actualWidth = (horizontalOuterLayout.getMeasuredWidth() - 512);
scrollMax = actualWidth;
}
public void startAutoScrolling()
{
if (scrollTimer == null)
{
scrollTimer = new Timer();
final Runnable Timer_Tick = new Runnable()
{
public void run()
{
moveScrollViewRight();
}
};
if (scrollerSchedule != null)
{
scrollerSchedule.cancel();
scrollerSchedule = null;
}
scrollerSchedule = new TimerTask()
{
#Override
public void run()
{
runOnUiThread(Timer_Tick);
}
};
scrollTimer.schedule(scrollerSchedule, 30, 30);
}
}
public void moveScrollViewRight()
{
scrollPos = (int) (horizontalScrollview.getScrollX() + 1.0);
if (scrollPos >= scrollMax)
{
scrollPos = 0;
}
horizontalScrollview.scrollTo(scrollPos, 0);
}
/** Adds the images to view. */
public void addImagesToView()
{
for (int i = 0; i < imageNameArray.length; i++)
{
final ImageView imageView = new ImageView(this);
int imageResourceId = getResources().getIdentifier(imageNameArray[i], "drawable", getPackageName());
Drawable image = this.getResources().getDrawable(imageResourceId);
imageView.setBackgroundDrawable(image);
imageView.setTag(i);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(180, 123);
params.setMargins(0, 25, 0, 25);
imageView.setLayoutParams(params);
horizontalOuterLayout.addView(imageView);
}
}
public void stopAutoScrolling()
{
if (scrollTimer != null)
{
scrollTimer.cancel();
scrollTimer = null;
}
}
public void onBackPressed()
{
super.onBackPressed();
finish();
}
public void onPause()
{
super.onPause();
finish();
}
public void onDestroy()
{
clearTimerTaks(clickSchedule);
clearTimerTaks(scrollerSchedule);
clearTimerTaks(faceAnimationSchedule);
clearTimers(scrollTimer);
clearTimers(faceTimer);
clickSchedule = null;
scrollerSchedule = null;
faceAnimationSchedule = null;
scrollTimer = null;
faceTimer = null;
super.onDestroy();
}
private void clearTimers(Timer timer)
{
if (timer != null)
{
timer.cancel();
timer = null;
}
}
private void clearTimerTaks(TimerTask timerTask)
{
if (timerTask != null)
{
timerTask.cancel();
timerTask = null;
}
}
scrolling back the other way would be easiest.
add in a instance variable that is set to 1.0 (called say scrollDist)
then change this line
scrollPos = (int) (horizontalScrollview.getScrollX() + 1.0);
to
scrollPos = (int) (horizontalScrollview.getScrollX() + scrollDist);
and this line
scrollPos = 0;
to
scrollDist *= -1.0;
this way it will reverse each time it hits the end of the scrollview.
For endless scrolling use the following snnipet
public void getScrollMaxAmount() {
int actualWidth = (horizontalOuterLayout.getMeasuredWidth() - getWindowManager().getDefaultDisplay().getWidth());
scrollMax = actualWidth;
}
public void moveScrollView() {
// ********************* Scrollable Speed ***********************
scrollPos = (int) (horizontalScrollview.getScrollX() + 1.0);
if (scrollPos >= scrollMax) {
Log.v("childCount", ""+scrollMax);
addImagesToView();
getScrollMaxAmount();
}
horizontalScrollview.scrollTo(scrollPos, 0);
}
I want to draw math-function like y=x^2+1 with androidPlot library.I have "SimpleXYPlot". It works but I don't know how to change it from sin to my function.
Here's the code:
public class DynamicXYPlotActivity extends Activity {
// redraws a plot whenever an update is received:
private class MyPlotUpdater implements Observer {
Plot plot;
public MyPlotUpdater(Plot plot) {
this.plot = plot;
}
#Override
public void update(Observable o, Object arg) {
plot.redraw();
}
}
private XYPlot dynamicPlot;
private MyPlotUpdater plotUpdater;
SampleDynamicXYDatasource data;
private Thread myThread;
#Override
public void onCreate(Bundle savedInstanceState) {
// android boilerplate stuff
super.onCreate(savedInstanceState);
setContentView(R.layout.dynamicxyplot_example);
// get handles to our View defined in layout.xml:
dynamicPlot = (XYPlot) findViewById(R.id.dynamicXYPlot);
plotUpdater = new MyPlotUpdater(dynamicPlot);
// only display whole numbers in domain labels
dynamicPlot.getGraphWidget().setDomainValueFormat(new DecimalFormat("0"));
// getInstance and position datasets:
data = new SampleDynamicXYDatasource();
SampleDynamicSeries sine1Series = new SampleDynamicSeries(data, 0, "Sine 1");
SampleDynamicSeries sine2Series = new SampleDynamicSeries(data, 1, "Sine 2");
LineAndPointFormatter formatter1 = new LineAndPointFormatter( Color.rgb(0, 0, 0), null, null, null );
formatter1.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
formatter1.getLinePaint().setStrokeWidth(10);
dynamicPlot.addSeries( sine1Series,formatter1 );
LineAndPointFormatter formatter2 = new LineAndPointFormatter(Color.rgb(0, 0, 200), null, null, null);
formatter2.getLinePaint().setStrokeWidth(10);
formatter2.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
//formatter2.getFillPaint().setAlpha(220);
dynamicPlot.addSeries(sine2Series, formatter2);
// hook up the plotUpdater to the data model:
data.addObserver(plotUpdater);
// thin out domain tick labels so they dont overlap each other:
dynamicPlot.setDomainStepMode(XYStepMode.INCREMENT_BY_VAL);
dynamicPlot.setDomainStepValue(5);
dynamicPlot.setRangeStepMode(XYStepMode.INCREMENT_BY_VAL);
dynamicPlot.setRangeStepValue(10);
dynamicPlot.setRangeValueFormat(new DecimalFormat("###.#"));
// uncomment this line to freeze the range boundaries:
dynamicPlot.setRangeBoundaries(-100, 100, BoundaryMode.FIXED);
// create a dash effect for domain and range grid lines:
DashPathEffect dashFx = new DashPathEffect(
new float[] {PixelUtils.dpToPix(3), PixelUtils.dpToPix(3)}, 0);
dynamicPlot.getGraphWidget().getDomainGridLinePaint().setPathEffect(dashFx);
dynamicPlot.getGraphWidget().getRangeGridLinePaint().setPathEffect(dashFx);
}
#Override
public void onResume() {
// kick off the data generating thread:
myThread = new Thread(data);
myThread.start();
super.onResume();
}
#Override
public void onPause() {
data.stopThread();
super.onPause();
}
class SampleDynamicXYDatasource implements Runnable {
// encapsulates management of the observers watching this datasource for update events:
class MyObservable extends Observable {
#Override
public void notifyObservers() {
setChanged();
super.notifyObservers();
}
}
private static final double FREQUENCY = 5; // larger is lower frequency
private static final int MAX_AMP_SEED = 100; //100
private static final int MIN_AMP_SEED = 10; //10
private static final int AMP_STEP = 1;
public static final int SINE1 = 0;
public static final int SINE2 = 1;
private static final int SAMPLE_SIZE = 30;
private int phase = 0;
private int sinAmp = 1;
private MyObservable notifier;
private boolean keepRunning = false;
{
notifier = new MyObservable();
}
public void stopThread() {
keepRunning = false;
}
//#Override
public void run() {
try {
keepRunning = true;
boolean isRising = true;
while (keepRunning) {
Thread.sleep(100); // decrease or remove to speed up the refresh rate.
phase++;
if (sinAmp >= MAX_AMP_SEED) {
isRising = false;
} else if (sinAmp <= MIN_AMP_SEED) {
isRising = true;
}
if (isRising) {
sinAmp += AMP_STEP;
} else {
sinAmp -= AMP_STEP;
}
notifier.notifyObservers();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public int getItemCount(int series) {
return SAMPLE_SIZE;
}
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index;
}
public Number getY(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
double angle = (index + (phase))/FREQUENCY;
double amp = sinAmp * Math.sin(angle);
switch (series) {
case SINE1:
return amp;
case SINE2:
return -amp;
default:
throw new IllegalArgumentException();
}
}
public void addObserver(Observer observer) {
notifier.addObserver(observer);
}
public void removeObserver(Observer observer) {
notifier.deleteObserver(observer);
}
}
class SampleDynamicSeries implements XYSeries {
private SampleDynamicXYDatasource datasource;
private int seriesIndex;
private String title;
public SampleDynamicSeries(SampleDynamicXYDatasource datasource, int seriesIndex, String title) {
this.datasource = datasource;
this.seriesIndex = seriesIndex;
this.title = title;
}
#Override
public String getTitle() {
return title;
}
#Override
public int size() {
return datasource.getItemCount(seriesIndex);
}
#Override
public Number getX(int index) {
return datasource.getX(seriesIndex, index);
}
#Override
public Number getY(int index) {
return datasource.getY(seriesIndex, index);
}
}
}
=======================================================
After what "Nick" said and other minor addition, I got this result:
but as we know :
https://www.google.com/search?q=y%3Dx%5E2%2B1&oq=y%3Dx%5E2%2B1&aqs=chrome..69i57j0l5.7056j0j7&sourceid=chrome&es_sm=93&ie=UTF-8
Now how to make the left side?
Using the code above can modify SampleDynamicXYDatasource to do what you want. All that code does is generate some data in a sine pattern. I don't know how your x values are going to be generated so here's a modified SampleDynamicXYDatasource.getY(...) that just uses the original code where x=index above and uses your function to generate the y-values:
public Number getY(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
Number x = getX(series, index);
double y = Math.pow(x.doubleValue(), 2) + 1;
switch (series) {
case SINE1:
return y;
case SINE2:
return -y;
default:
throw new IllegalArgumentException();
}
}
You'll notice that when you make this change, the plot appears to no longer be animated. (it actually still is but that's besides the point) This is because y is now purely a function of x and the x values never change.
As far as how to stop the animation, the plot redraws whenever plot.redraw() is called, which in the example above is in response to an event being continuously fired by events generated by the thread being run on the Runnable instance of SampleDynamicXYDatasource. Using the example above, the simplest way to stop the animation is to replace:
#Override
public void onResume() {
// kick off the data generating thread:
myThread = new Thread(data);
myThread.start();
super.onResume();
}
with:
#Override
public void onResume() {
dynamicPlot.redraw();
super.onResume();
}
Try replace this>>
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index;
}
To this>>
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index - 15;
}
How to detect rotation around Y axis of phone?
I am novice in android. I would like to detect 180 degrees rotation. I would like to detect for example if user flip phone which lies on a table or if user rotate his phone in his pocket.
I have read a lot of articles but I really don't understand how to get phone position and then compute angle between another position.
I have found for example this article but I don't know what to do with array named orientation:
Get device angle by using getOrientation() function
Thanks!
// Here is my solution. Not perfectly logical but works quite good:
public class FlipListener implements SensorEventListener {
SensorManager sensorMgr;
FlipEventReceiver receiver;
public FlipListener(Context context, FlipEventReceiver receiver) {
this.receiver = receiver;
sensorMgr = (SensorManager) context.getSystemService(Activity.SENSOR_SERVICE);
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI);
}
public void onResume() {
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI);
}
public void onPause() {
sensorMgr.unregisterListener(this);
clearStack();
}
private static final int IGNORE_FLIPS_AFTER_FLIP = 2500;
private static final int SAMPLING_INTERVAL = 60;
private static final int MINIMAL_STACK_SIZE_TO_FLIP = 2; // Shouldn't be lower than 2
private static final float FLIP_RADIANS = (float)Math.toRadians(140);
private static final int STACK_MAX_SIZE = 38;
private List<Float> stack = new ArrayList<Float>();
private long lastAdd = 0;
private long lastFlip = 0;
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
rotationRateAroundYChanged((float)event.values[1]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void rotationRateAroundYChanged(float rotationRateAroundY) {
long currentTime = System.currentTimeMillis();
if (lastFlip != 0 && (currentTime - lastFlip) < IGNORE_FLIPS_AFTER_FLIP) {
return;
}
if( (currentTime - lastAdd) >= SAMPLING_INTERVAL ) {
if( Math.abs(rotationRateAroundY) > 0.3 ) { // Smaller values are unimportant. They can make only mess.
addToStack(rotationRateAroundY);
checkForFlip();
}
}
}
private void checkForFlip() {
int stackSize = stack.size();
if( stackSize < MINIMAL_STACK_SIZE_TO_FLIP ) return;
float approximateAngleSummary = 0;
float val;
for(int i = 0; i < stackSize; i++) {
val = Math.abs(stack.get(i).floatValue());
// "+ Math.pow(val/4.58, 2) )" don't have a sense. Simply it works better with it.
approximateAngleSummary += ( (val + Math.pow(val/4.58, 2) ) / 1000 ) * SAMPLING_INTERVAL;
if( approximateAngleSummary >= FLIP_RADIANS ) {
triggerFlipDetected();
clearStack();
return;
}
}
}
private void clearStack() {
stack.clear();
}
private void addToStack(float val) {
lastAdd = System.currentTimeMillis();
int stackSize = stack.size();
if( stackSize > 0 && ((stack.get(stackSize-1) > 0 ? 1 : -1) != (val>0?1:-1) || stackSize > STACK_MAX_SIZE) ) {
clearStack();
}
stack.add(val);
}
private void triggerFlipDetected() {
lastFlip = System.currentTimeMillis();
receiver.onFlipDetected();
}
public interface FlipEventReceiver {
public void onFlipDetected();
}
}
Usage:
public class FlipTestActivity extends Activity implements FlipEventReceiver {
FlipListener flipListener;
boolean flipListenerActive = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flip_test);
flipListener = new FlipListener(this, this);
}
public void onFlipDetected() {
// What to do when flip detected
}
#Override
protected void onResume() {
super.onResume();
if( !flipListenerActive ) {
flipListener.onResume();
flipListenerActive = true;
}
}
#Override
protected void onPause() {
super.onPause();
if( flipListenerActive ) {
flipListener.onPause();
flipListenerActive = false;
}
}
}
SensorManager is a class that lets you access the device's sensors. Check here
Here is a nice tutorial about sensors
i´m new to Android programming and I have a Question.
I have a Countdown that will count down from 60 to zero when i am touching the screen.
I want now that this Countdown will survive the Activity lifecycling even when onDestroy is called. So I need a Service for that.
Wenn the countdown is finished a notification will be send. But if the user want to open the App again before the countdown in the Service is finished, no notification should be sended and the service has to be stopped.
What is the best practice to implement those features? What is here the way to go?
Thank you very much for answers!
My approach is that I have a class with the countdown methods and the service
//Countdownclass
TimerClass.java
public class TimerClass {
private static final String TAG = "MyLog";
private static final long TIMERINTERVAL = 1000;
//Eigenschaften --------------------------------------------------------------------
private boolean isActiv = false;
private Paint paint;
private long timerTime;
private double actualTime;
private int x;
private int y;
private CountDownTimer countDownTimer;
private String timeString;
//Konstruktor --------------------------------------------------------------------
public TimerClass(int x, int y) {
this.x = x;
this.y = y;
paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.YELLOW);
paint.setAntiAlias(true);
paint.setTextAlign(Align.RIGHT);
paint.setTextSize(70);
}
public TimerClass() {
}
//Methoden --------------------------------------------------------------------
public void draw(Canvas canvas) {
if(isActiv) {
canvas.drawText(timeString, x, y, paint);
}
}
public void createTimer(long timerTime) {
this.timerTime = timerTime;
countDownTimer = new CountDownTimer(timerTime, TIMERINTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
actualTime = (double) millisUntilFinished / TIMERINTERVAL;
NumberFormat nf = new DecimalFormat("##.#");
nf.format(actualTime);
if(actualTime < 10) {
new DecimalFormat();
timeString = "0:0" + nf.format(actualTime - 1);
} else {
timeString = "0:" + nf.format(actualTime - 1);
}
}
#Override
public void onFinish() {
isActiv = false;
}
};
}
public void timerStart() {
countDownTimer.start();
isActiv = true;
}
public void timerStop() {
if(isActiv) {
countDownTimer.cancel();
}
isActiv = false;
}
public boolean isActiv() {
return isActiv;
}
public void setActiv(boolean isActiv) {
this.isActiv = isActiv;
}
public double getActualTime() {
return actualTime;
}
public void setActualTime(double actualTime) {
this.actualTime = actualTime;
}
And my Service:
public class TimerService extends Service {
//class with the countdowntimer
private TimerClass timerClass;
private long startTime;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
timerClass = new TimerClass();
startTime = (long) timerClass.getActualTime();
timerClass.createTimer(startTime);
}
#Override
public void onDestroy() {
timerClass.timerStop();
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
timerClass.timerStart();
if(timerClass.getActualTime() <= 0) {
// send the notification
}
return super.onStartCommand(intent, flags, startId);
}
I wanted to start the Service in my mainActivies onPause method and stop it when onResume is called. But i´ve have tried it many times and failed.. so i have no code for my service in my activity.
( Sorry for my broken english :( )
I want one of my ViewGroup to be movable. Let's say, I want to click on it and the content below it reveals. On second click it closes again. Kind of sliding menu behaviour.
Here are my classes:
Custom scroller:
public class MyScroller implements Runnable {
private static final String TAG = "MY_SCROLLER";
private static final int ANIMATION_DURATION = 500;
private final Scroller mScroller;
private View mScrollingView;
private int lastX = 0;
private static final Interpolator sInterpolator = new Interpolator() {
public float getInterpolation(float t) {
t -= 1.0f;
return t * t * t * t * t + 1.0f;
}
};
MyScroller(final View view) {
mScroller = new android.widget.Scroller(view.getContext(), sInterpolator);
mScrollingView = view;
}
public void start(int initialVelocity) {
Log.d(TAG, "start() called");
int initialX = mScrollingView.getScrollX();
int maxX = mScrollingView.getWidth();
mScroller.startScroll(0, 0, maxX, 0, ANIMATION_DURATION);
lastX = initialX;
mScrollingView.post(this);
}
public void run() {
Log.d(TAG, "run() called");
if (mScroller.isFinished()) {
mScrollingView.invalidate();
return;
}
boolean more = mScroller.computeScrollOffset();
int x = mScroller.getCurrX();
int diff = x - lastX;
if (diff != 0) {
Log.d(TAG, "x = " + x);
mScrollingView.offsetLeftAndRight(diff);
mScrollingView.invalidate();
lastX = x;
} else {
forceFinished();
}
if (more) {
mScrollingView.postDelayed(this, 16);
}
}
void forceFinished() {
if (!mScroller.isFinished()) {
mScroller.forceFinished(true);
mScrollingView.invalidate();
}
}
}
and usage:
viewGroup.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new MyScroller(v).start(0);
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new MyScroller(v).start(0);
}
});
For Button everything works fine - it smoothly moves.
But ViewGroups that I tried leave a trail like on screenshot.
RelativeLayout with Button inside left a trail.
Standalone Button moved perfectly.
What am I missing here?