TimeStamp not working correctly, when changing Activity - java

Im really new to Android programming(started yesterday) and im currently working on an App that should give me the time between first time clicking a button and second time clicking the button.
It works fine when i stay in the Activity. But if i change the activity while the time is "running" and then reenter the main activity it gives me a strange timestamp.
How the timestamp works:
I have a button for Start/Stop
On clicking start it calls a Method where i get the current system time in milliseconds and saves it to a variable.
On clicking stop it does the same and subtracts endTime-startTime. Thats how i get the total time.
(Works fine)
But when changing activity(I got a button where it changes to an activity where i can add a customer) and reentering main and stopping the timer, it adds the totalTime up to something i cant relate to.. currently my stop time is at 45 minutes.
Maybe i do something wrong on saving my values?
I'll just post my code. Maybe someone can help me and give me a hint. Thanks and sorry for my bad english!
Class "Timerecording"
package com.example.cmsolutions.zeiterfassung;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.view.View;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
public class ZeitErfassen extends AppCompatActivity {
public static LinkedList<Kunde> kunden = new LinkedList();
boolean running = false;
long startTime,endTime,totalTime;
public Date date = new Date();
private SharedPreferences app_preferences;
private SharedPreferences.Editor editor;
private static final int PREFERENCE_MODE_PRIVAT=0;
private TextView displayTime;
public Button startEndButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zeit_erfassen);
//Einstellungen laden
app_preferences = getPreferences(PREFERENCE_MODE_PRIVAT);
displayTime = (TextView)findViewById(R.id.zeit_bei_Kunde);
startTime= app_preferences.getLong("startTime", 0);
endTime = app_preferences.getLong("endTime", 0);
running = app_preferences.getBoolean("running", false);
totalTime = app_preferences.getLong("totalTime", 0);
displayTime.setText((CharSequence) app_preferences.getString("zeitAnzeige", "Zeit bei Kunde"));
startEndButton = (Button)findViewById(R.id.start_Timer);
startEndButton.setText((CharSequence)app_preferences.getString("timerButton","Start Timer"));
editor = app_preferences.edit();
editor.commit();
createDropDown();
}
public void startTimer(View view) {
if(running == false) {
startTime = getTime();
displayTime.setText("Zeitstoppung läuft");
editor.putString("zeitAnzeige",(String)displayTime.getText());
running = true;
editor.putBoolean("running",true);
editor.putLong("startTimer", startTime);
startEndButton.setText("End Timer");
editor.putString("timerButton", (String)startEndButton.getText());
editor.commit();
} else {
endTime = getTime();
editor.putLong("endTime",endTime);
totalTime = endTime - startTime;
editor.putLong("totalTime",totalTime);
int hours = (int) ((totalTime / (1000*60*60)) % 24);
int minutes = (int) ((totalTime / (1000*60)) % 60);
int seconds = (int) (totalTime / 1000) % 60;
displayTime.setText(String.valueOf(hours)+ ":"+String.valueOf(minutes)+":"+ String.valueOf(seconds));
startEndButton.setText("Start Timer");
editor.putString("timerButton",(String)startEndButton.getText());
editor.commit();
running = false;
}
}
public void neuerKunde(View view) {
Intent intent = new Intent(this, AddKunde.class);
startActivity(intent);
}
public long getTime() {
long millis = System.currentTimeMillis();
return millis;
}
public void createDropDown() {
if(kunden.size() > 0) {
Spinner spinner = (Spinner) findViewById(R.id.chooseCustomer);
ArrayList<String> names = new ArrayList<>();
for(Kunde k:kunden) {
names.add(k.getName());
}
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, names);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
}
}
}
Class"AddCusomter"
package com.example.cmsolutions.zeiterfassung;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.EditText;
import java.util.LinkedList;
public class AddKunde extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_kunde2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void addKunde(View view) throws Exception {
try {
EditText strings = (EditText) findViewById(R.id.customerName);
String name = strings.getText().toString();
strings = (EditText) findViewById(R.id.addressField);
String address = strings.getText().toString();
Kunde customer = new Kunde(name,address);
ZeitErfassen.kunden.add(customer);
} catch (Exception e) {
throw new Exception("Fehler in addKunde!");
}
startActivity(new Intent(this,ZeitErfassen.class));
}
}
I just realised, maybe its because at the end of method addKunde() I start the MainActivity again?
PS: I think that I could also improve my Coding Style. If you have any Tips regarding better coding(methods to other class,....), im also greatuful! Thanks!

Instead of start activity you can finish activity.
//startActivity(new Intent(this,ZeitErfassen.class));
finish();
Check the shared pref is XML is storing values using ddms.
Open shared prefs only when you need
//OnCreate
app_preferences = getApplicationContext().getSharedPreferences("MyPref", MODE_PRIVATE);
Editor editor = pref.edit();
public void startTimer(View view) {
SharedPreferences.Editor editor = = app_preferences.edit();
if(running == false) {
startTime = getTime(); displayTime.setText("Zeitstoppung läuft");
editor.putString("zeitAnzeige",(String)displayTime.getText());
running = true;
editor.putBoolean("running",true); editor.putLong("startTimer", startTime);
startEndButton.setText("End Timer");
editor.putString("timerButton", (String)startEndButton.getText());
editor.commit();
} else {
endTime = getTime();
editor.putLong("endTime",endTime); totalTime = endTime - startTime;
editor.putLong("totalTime",totalTime);
int hours = (int) ((totalTime / (1000*60*60)) % 24); int minutes = (int) ((totalTime / (1000*60)) % 60);
int seconds = (int) (totalTime / 1000) % 60;
displayTime.setText(String.valueOf(hours)+ ":"+String.valueOf(minutes)+":"+ String.valueOf(seconds));
startEndButton.setText("Start Timer"); editor.putString("timerButton",(String)startEndButton.getText());
editor.commit();
running = false;
}
}

Related

How do I set my android studio project as my phones background?

I have created an android studio project that contains a countdown until Christmas. I use two images to create the background and the outline for the countdown timer. I have made the application look nice and I was wondering if there is any way to set the project as my phone's background and if it is possible how to do it. The code below is how I set the timer and give it its value. Is there anything I need to change to make this possible?
package com.example.holidaycountdown;
import android.app.WallpaperManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MainActivity extends AppCompatActivity {
private TextView txtTimerDay, txtTimerHour, txtTimerMinute, txtTimerSecond;
private TextView tvEvent;
private Handler handler;
private Runnable runnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtTimerDay = (TextView) findViewById(R.id.txtTimerDay);
txtTimerHour = (TextView) findViewById(R.id.txtTimerHour);
txtTimerMinute = (TextView) findViewById(R.id.txtTimerMinute);
txtTimerSecond = (TextView) findViewById(R.id.txtTimerSecond);
tvEvent = (TextView) findViewById(R.id.tvhappyevent);
countDownStart();
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setWallpaper();
}
});
}
private void setWallpaper() {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.wallpaper);
WallpaperManager manager = WallpaperManager.getInstance(getApplicationContext());
try{
manager.setBitmap(bitmap);
Toast.makeText(this, "Wallpaper set!", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
Toast.makeText(this, "Error!", Toast.LENGTH_SHORT).show();
}
}
public void countDownStart() {
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 1000);
try {
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd");
// Please here set your event date//YYYY-MM-DD
Date futureDate = dateFormat.parse("2020-12-25");
Date currentDate = new Date();
if (!currentDate.after(futureDate)) {
long diff = futureDate.getTime()
- currentDate.getTime();
long days = diff / (24 * 60 * 60 * 1000);
diff -= days * (24 * 60 * 60 * 1000);
long hours = diff / (60 * 60 * 1000);
diff -= hours * (60 * 60 * 1000);
long minutes = diff / (60 * 1000);
diff -= minutes * (60 * 1000);
long seconds = diff / 1000;
txtTimerDay.setText("" + String.format("%02d", days));
txtTimerHour.setText("" + String.format("%02d", hours));
txtTimerMinute.setText(""
+ String.format("%02d", minutes));
txtTimerSecond.setText(""
+ String.format("%02d", seconds));
} else {
tvEvent.setVisibility(View.VISIBLE);
tvEvent.setText("The event started!");
textViewGone();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
handler.postDelayed(runnable, 1 * 1000);
}
public void textViewGone() {
findViewById(R.id.LinearLayout10).setVisibility(View.GONE);
findViewById(R.id.LinearLayout11).setVisibility(View.GONE);
findViewById(R.id.LinearLayout12).setVisibility(View.GONE);
findViewById(R.id.LinearLayout13).setVisibility(View.GONE);
findViewById(R.id.textView1).setVisibility(View.GONE);
findViewById(R.id.textView2).setVisibility(View.GONE);
}
}
Seems like you need to create an app widget for your application(App Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates).
Here is a useful tutorial
Google's tutorial

Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference error

I am trying to get a notification to trigger when a long is below a certain number. However whenever sendNotification() is called it throws the above error.
I am new to android.
Below is the section of the code where the issue is.
I am not sure what is causing this error. I supect I made need to change the method to sendNotification(View view) but in that case what do I send as the view?
I can provide the full code if needed.
package com.mple.seriestracker;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import com.mple.seriestracker.activity.HomeScreenActivity;
import com.mple.seriestracker.api.episodate.entities.show.Episode;
import com.mple.seriestracker.util.NotificationGenerator;
import org.threeten.bp.Duration;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.OffsetDateTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.ZoneOffset;
import org.threeten.bp.ZonedDateTime;
import org.threeten.bp.format.DateTimeFormatter;
import java.util.Locale;
public class Countdown extends AppCompatActivity{
private int season;
private int episode;
private String name;
private ZonedDateTime airDate;
private Context context;
public Countdown(String name, int episode,int season,ZonedDateTime airDate, Context context){
this.airDate = airDate;
this.name = name;
this.episode = episode;
this.season = season;
this.context = context;
}
public Countdown(com.mple.seriestracker.api.episodate.entities.show.Countdown countdown){
this.airDate = parseToLocal(countdown.air_date);
this.name = countdown.name;
this.episode = countdown.episode;
this.season = countdown.season;
}
public void getSecondsTillAiring(){
Duration duration = Duration.between(LocalDateTime.now(),airDate);
long days = duration.toDays();
//No idea why this returns an absurd number, possibly something wrong with the time conversion
//So the simple fix is to convert the days into hours, subtract the total hours with the days.
//This returns the real value, and makes it accurate.
long hours = duration.toHours()-(days*24);
long minutes = (int) ((duration.getSeconds() % (60 * 60)) / 60);
long seconds = (int) (duration.getSeconds() % 60);
if(days > 0){
hours += days * 24;
}
if(hours > 0){
minutes += 60* hours;
}
if(minutes > 0){
seconds += 60 * minutes;
}
if (seconds < 432000){
sendNotification();
}
}
public void sendNotification()
{
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "M_CH_ID");
//Create the intent that’ll fire when the user taps the notification//
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.androidauthority.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
notificationBuilder.setContentIntent(pendingIntent);
NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel =
new NotificationChannel("M_CH_ID", "M_CH_ID", NotificationManager.IMPORTANCE_DEFAULT);
notificationChannel.setDescription("Test");
nm.createNotificationChannel(notificationChannel);
notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("Hearty365")
.setContentTitle("Default notification")
.setContentText("Random words")
.setContentInfo("Info");
nm.notify(1, notificationBuilder.build());
}
public String getCountdownFormat(){
getSecondsTillAiring();
Duration duration = Duration.between(LocalDateTime.now(),airDate);
long days = duration.toDays();
//No idea why this returns an absurd number, possibly something wrong with the time conversion
//So the simple fix is to convert the days into hours, subtract the total hours with the days.
//This returns the real value, and makes it accurate.
long hours = duration.toHours()-(days*24);
int minutes = (int) ((duration.getSeconds() % (60 * 60)) / 60);
int seconds = (int) (duration.getSeconds() % 60);
String timeString = "";
if(days > 0){
timeString+=formatDay(days);
}
if(hours > 0){
timeString+=formatHour(hours);
}
if(minutes > 0){
timeString+= formatMinutes(minutes);
}
if(seconds > 0){
timeString += formatSeconds(seconds);
}
return timeString;
}
public String getName() {
return name;
}
public int getEpisode() {
return episode;
}
public int getSeason() {
return season;
}
private String formatDay(long days){
return format(days,"day");
}
private String formatHour(long hours){
return format(hours,"hour");
}
private String formatMinutes(long minutes){
return format(minutes,"minute");
}
private String formatSeconds(long seconds){
return format(seconds,"second");
}
private String format(long x,String nonPlural){
//Checks whether or not a plural should be added
String string = nonPlural;
if(x > 1)
string+="s";
return String.format("%s %s ",x,string);
}
//All air dates are formatted in this format
static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
public static ZonedDateTime parseToLocal(String s){
if(s == null) return null;
return LocalDateTime.parse(s, DATE_TIME_FORMATTER)
.atOffset(ZoneOffset.UTC)
.atZoneSameInstant(ZoneId.systemDefault());
}
public static boolean isOlderEpisode(LocalDateTime airDate, LocalDateTime currEpDate){
return currEpDate.isBefore(airDate);
}
public static boolean isOlderEpisode(OffsetDateTime airDate, OffsetDateTime currEpDate){
return currEpDate.toLocalDate().isBefore(airDate.toLocalDate());
}
//Responsible for finding a certain episode
public Countdown getUpcomingAiringEp(Episode[] episodes, int episode, int season) {
if (episodes == null) {
return null;
}
//Loop in reverse, since the episodes are ordered from start to finish
//So looping from reverse will start with the newer shows first
for (int i = (episodes.length - 1); i >= 0; i--) {
Episode newEpisode = episodes[i];
if (newEpisode.air_date != null && newEpisode.season == season && newEpisode.episode == episode) {
return new Countdown(newEpisode.name,newEpisode.episode, newEpisode.season, parseToLocal(newEpisode.air_date),this);
}
if(newEpisode.season <= (newEpisode.season - 1)) {
break;
}
}
return null;
}
}
Full stack trace
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mple.seriestracker, PID: 2348
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:145)
at android.app.PendingIntent.getActivity(PendingIntent.java:344)
at android.app.PendingIntent.getActivity(PendingIntent.java:311)
at com.mple.seriestracker.Countdown.sendNotification(Countdown.java:76)
at com.mple.seriestracker.Countdown.getSecondsTillAiring(Countdown.java:65)
at com.mple.seriestracker.Countdown.getCountdownFormat(Countdown.java:100)
at com.mple.seriestracker.fragments.CountdownFragment$RecyclerViewAdapter$1.run(CountdownFragment.java:95)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
And the main class
package com.mple.seriestracker.activity;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.content.ContextCompat;
import androidx.viewpager.widget.ViewPager;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;
import com.jakewharton.threetenabp.AndroidThreeTen;
import com.mple.seriestracker.R;
import com.mple.seriestracker.ShowInfo;
import com.mple.seriestracker.ShowTracker;
import com.mple.seriestracker.TvShow;
import com.mple.seriestracker.api.episodate.Episodate;
import com.mple.seriestracker.api.episodate.entities.show.TvShowResult;
import com.mple.seriestracker.database.EpisodeTrackDatabase;
import com.mple.seriestracker.fragments.CountdownFragment;
import com.mple.seriestracker.fragments.SectionsPagerAdapter;
import com.mple.seriestracker.fragments.MyShowsFragment;
import com.mple.seriestracker.util.NotificationGenerator;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Response;
public class HomeScreenActivity extends AppCompatActivity {
static final int NEW_SHOW_REQUEST_CODE = 1;
static final int FILE_PERMISSION_RREQUEST_CODE = 1;
static final int NEW_SHOW_REQUEST_RESULT_CODE = 1;
Context context = this;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
TabLayout mTabs;
boolean started = false;
//TODO allow more than 3 shows to display on countdown page
//TODO sort the countdown tab based on time
//TODO notify the user when a show is airing
//TODO re-obtain the next countdown (if any new episodes) otherwise remove the countdown from the tab
//TODO add delete button to delete shows (holding on image already has checkboxes implemented)
//All done after that
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EpisodeTrackDatabase.setInstance(new EpisodeTrackDatabase(getApplicationContext()));
//Sets all date time stuff to correct sync
AndroidThreeTen.init(this);
//Initialize fragments
mSectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
mViewPager = findViewById(R.id.view_pager);
setupViewPager(mViewPager);
mTabs = findViewById(R.id.tabs);
mTabs.setupWithViewPager(mViewPager);
//Initialize floating menu button
FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startSearchIntent();
}
});
}
#Override
protected void onStart() {
super.onStart();
//On start is called when the search intent is destroyed
//This prevents it from being used more than once.
//As it's intended for loading settings only (after all UI elements are initialized)
if(started) return;
loadSettings();
started = true;
}
//Responsible for setting up the fragments for each tab
private void setupViewPager(ViewPager viewPager){
mSectionsPagerAdapter.addFragment(new MyShowsFragment(),"My Shows");
mSectionsPagerAdapter.addFragment(new CountdownFragment(),"Countdowns");
viewPager.setAdapter(mSectionsPagerAdapter);
}
private void loadSettings(){
//Loads settings from database
new LoadShowsTask().execute();
}
//Adds a show to the "my shows" tab
public void addShow(ShowInfo showInfo){
new TvShowTask().execute(showInfo); //Background task to get info from the api
EpisodeTrackDatabase.INSTANCE.addShow(showInfo.name,showInfo.imagePath,showInfo.id); //Add the show to the database
((MyShowsFragment)mSectionsPagerAdapter.getItem(0)).addShow(showInfo); //Adds it to the fragment, fragment will then automatically update it
}
public void addCountdown(long showID){
if(ShowTracker.INSTANCE.calenderCache.contains(showID))return;
((CountdownFragment)mSectionsPagerAdapter.getItem(1)).addCountdown(showID);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == NEW_SHOW_REQUEST_CODE && resultCode == NEW_SHOW_REQUEST_RESULT_CODE) {
//Create a new show, add it to the list and populate it
ShowInfo showInfo = new ShowInfo(); //Creates a new object
showInfo.id = data.getLongExtra("showID",0);
showInfo.imagePath = data.getStringExtra("showImage");
showInfo.name = data.getStringExtra("showName");
ShowTracker.INSTANCE.addedShowsCache.add(showInfo.id);
addShow(showInfo);
}
}
class LoadShowsTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... strings) {
ShowInfo[] showData = EpisodeTrackDatabase.INSTANCE.getAllShows();
runOnUiThread(() ->{
new TvShowTask().execute(showData);
for (ShowInfo show : showData) {
runOnUiThread(() ->addShow(show));
}
});
return null;
}
}
class TvShowTask extends AsyncTask<ShowInfo,Void, List<TvShowResult>> {
//Responsible for obtaining info about each show
//Automatically prompts on each show add/app initialization
#Override
protected List<TvShowResult> doInBackground(ShowInfo ... shows) {
List<TvShowResult> tvShowResults = new ArrayList<>();
for (ShowInfo show: shows) {
try {
Response<com.mple.seriestracker.api.episodate.entities.show.TvShow> response = Episodate.INSTANCE
.show()
.textQuery(show.id + "")
.execute();
if(response.isSuccessful()){
tvShowResults.add(response.body().tvShow);
}
} catch (IOException e) {}
}
return tvShowResults;
}
#Override
protected void onPostExecute(List<TvShowResult> result) {
for (TvShowResult tvShowResult : result) {
TvShow tvShow = new TvShow(tvShowResult);
ShowTracker.INSTANCE.addTvShow(tvShow);
if(tvShow.getCountdown() != null){
addCountdown(tvShow.getId());
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode){
case FILE_PERMISSION_RREQUEST_CODE:
if(grantResults[0] == PackageManager.PERMISSION_GRANTED){
//Todo Finish this, if we will be implementing saving
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
break;
}
}
//Prevents the app opening multiple search intents, if spammed
void startSearchIntent(){
if(!ShowSearchActivity.destroyed) return;
Intent intent = new Intent(getApplicationContext(),ShowSearchActivity.class);
startActivityForResult(intent,NEW_SHOW_REQUEST_CODE);
}
//Will be used for writing saved data, later on to keep track of what shows are saved
boolean hasFilePermissions(){
return (Build.VERSION.SDK_INT > 22 && ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED);
}
void askForPermission(){
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, FILE_PERMISSION_RREQUEST_CODE);
}
}
Iam wondering if at this point it is just easiier to link to github as there are more classes than just these 2.
You must supply the proper Context from you Activity class.
First in your YOUR_ACTIVITY.java declare this
Context context = this;
then add context parameters in your countdown method
private int season;
private int episode;
private String name;
private ZonedDateTime airDate;
private Context context;
public Countdown(String name, int episode,int season,ZonedDateTime airDate, Context context){
this.airDate = airDate;
this.name = name;
this.episode = episode;
this.season = season;
this.context = context;
}
Just add the context when calling the Countdown method.
new Countdown(name, episode, season, context).getSecondsTillAiring();
then supply the context to NotificationManager like this.
NotificationManager nm = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Just remove "extends AppCompatActivity" might work for you, because apparently your class does not inherit anything from AppCompatActivity.
EDIT:
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
You may consider moving this part of the code to your Activity class,
or passing activity reference to the method and call it like:
NotificationManager nm = (NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);

Calculate Velocity TYPE_COUNTER_STEP SENSOR

I am very close to finish my project that is related to count steps , distance covered and calculate velocity. I am using TYPE_COUNTER_STEP sensor to calculate the steps and using formulas to calculate distance i.e 0.415 for men and 0.413 for women to get foot length by multiplying with height So far every thing is working fine But i am suck to calculate the velocity. I do not know how to calculate, i mean i know s = vt but i need time to get the velocity/step. Anyone have any idea how to achieve that. This is the last part of my project. I have also look for it on the internet but i did not get working method to calculate the time. Someone suggest me to use timestamp but i used that but unfortunately i get infinity text instead of velocity
I cannot use GPS to calculate the velocity because GPS is not available all the time i.e inside tunnel or underground etc
Thanks
package com.lijianzhong13354146.coeur1;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.format.DateUtils;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class AccurateStepCounter extends AppCompatActivity {
private long timestamp;
private TextView textViewStepCounter;
private TextView textViewStepDetector;
private Thread detectorTimeStampUpdaterThread;
private Handler handler;
Toolbar toolbar ;
private Button buttonStop ;
TextView stepValue ;
TextView distanceValue ;
TextView distanceTitle ;
int getCurrentStepValue ;
int actualStepTaken ;
SharedPreferences sharedPreferences ;
SharedPreferences.Editor editor ;
SharedPreferences sharedPreferencesFromSetting ;
SharedPreferences.Editor editorFromSetting ;
private boolean isRunning = true;
ArrayList<Step> arrayList ;
String gettingPersonHeight ;
double gettingPersonHeightInDoule ;
double step_length ;
SharedPreferences getSharedPreferencesHeight ;
SharedPreferences.Editor getEditoHeight ;
double timeInSecond ;
SharedPreferences sharedPreferencesGetGender ;
SharedPreferences.Editor editorGetGender;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_accurate_step_counter);
buttonStop = (Button) findViewById(R.id.buttonSTOP);
toolbar = (Toolbar) findViewById(R.id.toolbar);
stepValue = (TextView) findViewById(R.id.step_value);
distanceValue = (TextView) findViewById(R.id.distance_value);
arrayList = new ArrayList<>();
sharedPreferences = getSharedPreferences("saveInformation" , MODE_PRIVATE) ;
sharedPreferencesFromSetting = getSharedPreferences("EmailSave" , MODE_PRIVATE);
sharedPreferencesGetGender = getSharedPreferences("saveInformation" , MODE_PRIVATE);
getSharedPreferencesHeight = getSharedPreferences("Height" , MODE_PRIVATE);
distanceTitle = (TextView) findViewById(R.id.distance_title);
gettingPersonHeightInDoule = Double.parseDouble(
getSharedPreferencesHeight.getString("saveHeight" , "0"))/100;
if (sharedPreferencesGetGender.getString("GENDER" , null).equals("Male") ){
step_length = 0.415 * gettingPersonHeightInDoule ;
}else {
step_length = 0.413 * gettingPersonHeightInDoule ;
}
ToolbarConfig();
MediaPlayer mediaPlayer1 = MediaPlayer.create(this , R.raw.boom);
mediaPlayer1.start();
registerForSensorEvents();
onStopButtonClick();
// setupDetectorTimestampUpdaterThread();
}
#Override
public void onBackPressed() {
}
public void onStopButtonClick () {
buttonStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int actualSteps = getCurrentStepValue - arrayList.get(0);
editor = sharedPreferences.edit() ;
editor.putString("STEPS" , String.valueOf(actualSteps));
editor.commit() ;
startActivity(new Intent(AccurateStepCounter.this , FinalResultDisplay.class));
}
});
}
public void ToolbarConfig () {
toolbar.setTitle(getResources().getString(R.string.app_title));
toolbar.setSubtitle("Pedometer");
toolbar.setTitleTextColor(Color.WHITE);
toolbar.setSubtitleTextColor(Color.WHITE);
setSupportActionBar(toolbar);
}
public void registerForSensorEvents() {
SensorManager sManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// Step Counter
sManager.registerListener(new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
Step step = new Step(event.values[0], System.currentTimeMillis());
arrayList.add(step);
getCurrentStepValue = (int) step.getStep();
stepValue.setText(getCurrentStepValue - arrayList.get(0) + "");
double distaneCovered = step_length * (getCurrentStepValue - arrayList.get(0));
// the elapsed time beetween 2 step will be:
if (arrayList.size() > 2) {
Step lastStep = arrayList.get(arrayList.size() - 1);
Step previousStep = arrayList.get(arrayList.size() - 2);
long msElapsedTime = lastStep.getTimestamp() - previousStep.getTimestamp();
timeInSecond = TimeUnit.MILLISECONDS.toSeconds(msElapsedTime);
}
double getVelocity = distaneCovered / timeInSecond ;
// distanceTitle shows the speed for now
distanceTitle.setText(getVelocity + " m/s");
distanceValue.setText("" + distaneCovered);
/* float steps = event.values[0];
arrayList.add((int)steps);
getCurrentStepValue = (int) steps ;
double distanceCovered = (step_length * (getCurrentStepValue - arrayList.get(0))) /1000;
stepValue.setText(getCurrentStepValue - arrayList.get(0) + "");
distanceValue.setText("" + String.format("%.2f" , distanceCovered));*/
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}, sManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_FASTEST);
}
}
class Step {
private float step;
private long timestamp;
Step (float step , long timestamp) {
this.step = step;
this.timestamp = timestamp ;
}
public void setStep(float step) {
this.step = step;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public float getStep() {
return step;
}
public long getTimestamp() {
return timestamp;
}
// getters
// setters
}
You can calculate the elapsed time beetween 2 steps creating a Step class containing the timestamp as field. Then subtract the previous timestamp at the last!
public class Step {
private float step;
private long timestamp;
// constructor
// getters
// setters
}
#Override
public void onSensorChanged(SensorEvent event) {
Step step = new Step(event.values[0], System.currentTimeMillis());
arrayList.add(step);
getCurrentStepValue = (int) step.getStep();
stepValue.setText(getCurrentStepValue - arrayList.get(0) + "");
double distaneCovered = step_length * (getCurrentStepValue - arrayList.get(0));
// the elapsed time beetween 2 step will be:
if (arrayList.size() > 2) {
Step lastStep = arrayList.get(arrayList.size() - 1);
Step previousStep = arrayList.get(arrayList.size() - 2);
long msElapsedTime = lastStep.getTimestamp() - previousStep.getTimestamp();
}
distanceValue.setText("" + distaneCovered);
}
So you can do s=v/t

Android Java : Error while running countdown timer

I need your help to find an error in my "test" android application.
Until I create the second function "setProgessBar" the app runs without error, but now the error occur everytime. To comment the function call out has no effect.
Here is the code:
package my.timer;
import android.os.CountDownTimer;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class Timer1 extends AppCompatActivity {
private int arrayPosition = 0;
private long timeValue = 0;
private boolean indicator = false;
private double progress;
private final String[] actions = {"Phase1" , "Phase2" , "Phase3" , "Phase4"};
private final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer1);
final Button startButton = (Button) findViewById(R.id.startButton);
final TextView text1 = (TextView) findViewById(R.id.textView3);
final TextView text2 = (TextView) findViewById(R.id.actionParameter);
startButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
text2.setText(actions[arrayPosition]);
text1.setText("" + timeValue + "");
new CountDownTimer(240000, 100) {
public void onTick(long millisUntilFinished) {
timeValue = (millisUntilFinished / 1000) % 4;
text1.setText("" + timeValue + "");
if (timeValue == 3 && indicator){
if (arrayPosition < 3){
arrayPosition++;
} else {
arrayPosition = 0;
}
indicator = false;
setProgressBar(arrayPosition);
text2.setText(actions[arrayPosition]);
}
if (timeValue == 1){
indicator = true;
}
}
public void onFinish() {
text1.setText("Geschafft :)");
}
}.start();
}
});
}
private void setProgressBar(int progressStatus) {
switch (progressStatus){
case 0:
progress = progress + 0.25;
break;
case 2:
progress = progress - 0.25;
break;
}
progressBar.setProgress((int)progress);
}
}
Many thanks in advance
Tim

starting my countdown clock when activity is open

I am a bit of a keen novice at Android! I have a snippet of code for timer I want to use in my app however it works when the button is clicked and I want it to work when I open the activity that it is on. I have tried so many solutions but cannot get it to operate. Would really appreciate any help, I have tried putting an if statement in, I have tried using the onStart, and putting it the OnCreate all with no joy. The closest I can get is that it just starts with "Time Up!" in the field.
import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity
{
Button buttonStartTime;
TextView textViewShowTime;
CountDownTimer countDownTimer;
long totalTimeCountInMilliseconds;
long timeBlinkInMilliseconds;
boolean blink;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getReferenceOfViews ();
setActionListeners ();
totalTimeCountInMilliseconds = 60 * 1000;
timeBlinkInMilliseconds = 30 * 1000;
}
private void setActionListeners() {
buttonStartTime.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
textViewShowTime.setTextAppearance(getApplicationContext(), R.style.normalText);
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
if ( leftTimeInMilliseconds < timeBlinkInMilliseconds ) {
textViewShowTime.setTextAppearance(getApplicationContext(), R.style.blinkText);
if ( blink ) {
textViewShowTime.setVisibility(View.VISIBLE);
} else {
textViewShowTime.setVisibility(View.INVISIBLE);
}
blink = !blink;
}
textViewShowTime.setText(String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60));
}
#Override
public void onFinish()
textViewShowTime.setText("Time up!");
textViewShowTime.setVisibility(View.VISIBLE);
}
}.start();
}
}
);
}
private void getReferenceOfViews() {
buttonStartTime = (Button) findViewById(R.id.btnStartTime);
textViewShowTime = (TextView) findViewById(R.id.tvTimeCount);
}
}
You can modify your onResume() as :
#Override
public void onResume(){
buttonStartTime.performClick();
super.onResume();
}
You should make buttonStartTime a global variable for the class.

Categories