I'm trying to make a countdown in a notification for an application: When the application gets a notification, the notification has 20 seconds to disappear. Here is my code, but my application breaks as soon as it gets the notification, I hope somebody can help me, thanks:
package com.taxicell;
import java.util.ArrayList;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
/**
*Falta por descubrir
* #author sergio
*/
public class Notifica {
private Context context;
private String data[];
public timer timer;
public void Nueva(Context con,String dat){
Log.v("app", "nueva notificacion con los datos: "+dat);
context = con;
NotificationManager notificador =(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// Notification notifica=new Notification(R.drawable.taxicell,"TaxiCell !",System.currentTimeMillis());
Notification notifica=new Notification(R.drawable.taxicell,"TaxiCell !",30000);
notifica.defaults |= Notification.DEFAULT_SOUND;
notifica.defaults |= Notification.DEFAULT_LIGHTS;
notifica.flags |= Notification.FLAG_AUTO_CANCEL;
notifica.defaults |= Notification.DEFAULT_SOUND;
notifica.defaults |= Notification.DEFAULT_VIBRATE;
String mensajin="";
Intent intentoNotifica;
data=dat.split(",");
if(Validacion(dat)){
intentoNotifica=new Intent(context,Mensaje.class);
Bundle datos = new Bundle();
datos.putString("msj",dat );
datos.putInt("tipo", 0);
intentoNotifica.putExtras(datos);
mensajin="Solicitud de Servicio !";
}else{
intentoNotifica=new Intent(context,Mensaje.class);
Bundle datos = new Bundle();
datos.putString("msj",dat);
datos.putInt("tipo", 1);
intentoNotifica.putExtras(datos);
mensajin="Asignación de Saldo !";
}
Log.v("pm", "1");
timer = new timer();
Log.v("pr", "2");
timer.execute("ejecucion");
PendingIntent penIntent = PendingIntent.getActivity(context, 0, intentoNotifica,android.content.Intent.FLAG_ACTIVITY_NEW_TASK);
notifica.setLatestEventInfo(context,"TaxiCell",mensajin, penIntent);
notificador.notify(1,notifica);
}
....
....
private class timer extends AsyncTask<String, Integer, Integer>{
#Override
protected void onPreExecute() {
Log.v("loop","0");
}
protected Integer doInBackground(String... urls) {
Log.v("loop","1");
int i=10;
while( i > 0) {
if(isCancelled()){break;}
else{
try {Thread.sleep(1000); }
catch (InterruptedException e) {}
publishProgress(i); //Actualizamos los valores
Log.v("loop","2 es: "+i);
i--;
}
}
return i;
}
#Override
protected void onProgressUpdate (Integer... valores) {
}
#Override
protected void onPostExecute(Integer res) {
rechazarServ();
}
}
}
Related
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);
I am working on GoogleFit Api for daily steps count. I am getting the correct result. But when i sign out the application (In this case, app exit the Googlefit fragment's parent activity)
After sign in again, i access the same fragment again, but Googlefit returns the stepsCount as zero and getting times out at result.await.
Here is my Code.
GoogleFitFragment.java
package com.example.mudasirrao.mvvm.Fragments.GoogleFitFragments;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.mudasirrao.mvvm.R;
import com.example.mudasirrao.mvvm.ViewModel.GoogleFitViewModels.GoogleFitViewModel;
import com.example.mudasirrao.mvvm.databinding.FragmentGoogleFitBinding;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.ConfigApi;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.result.DataTypeResult;
public class GoogleFitFragment extends Fragment {
GoogleFitViewModel googleFitViewModel;
public GoogleFitFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
FragmentGoogleFitBinding fragmentGoogleFitBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_google_fit, container, false);
View view = fragmentGoogleFitBinding.getRoot();
googleFitViewModel = new GoogleFitViewModel(getActivity(), fragmentGoogleFitBinding);
fragmentGoogleFitBinding.setGoogleFitFragmentViewModel(googleFitViewModel);
return view;
}
}
GoogleFitViewModel.java
package com.example.mudasirrao.mvvm.ViewModel.GoogleFitViewModels;
import android.content.Context;
import android.content.SharedPreferences;
import android.databinding.ObservableField;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.mudasirrao.mvvm.CallBacks.CallBackGoogleFitClient;
import com.example.mudasirrao.mvvm.DataManager.GoogleFitDataManager;
import com.example.mudasirrao.mvvm.databinding.FragmentGoogleFitBinding;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.fitness.ConfigApi;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.result.DailyTotalResult;
import java.util.concurrent.TimeUnit;
import static android.content.Context.MODE_PRIVATE;
public class GoogleFitViewModel {
private Context context;
private FragmentGoogleFitBinding fragmentGoogleFitBinding;
public final ObservableField<String> steps = new ObservableField<>();
public GoogleApiClient localGoogleApiClient;
String dailySteps;
public GoogleFitViewModel(Context context, final FragmentGoogleFitBinding fragmentGoogleFitBinding) {
this.context = context;
this.fragmentGoogleFitBinding = fragmentGoogleFitBinding;
SharedPreferences prefs = context.getSharedPreferences("dailySteps", MODE_PRIVATE);
dailySteps = prefs.getString("daily_steps", null);
if (dailySteps != null) {
steps.set(dailySteps);
GoogleFitDataManager.singletonObject(context).buildFitnessClient(new CallBackGoogleFitClient() {
#Override
public void onResponse(GoogleApiClient googleApiClient) {
localGoogleApiClient = googleApiClient;
if (googleApiClient != null) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.previewImage.setVisibility(View.GONE);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
fragmentGoogleFitBinding.goalProgressLayout.setVisibility(View.VISIBLE);
fragmentGoogleFitBinding.goalText.setText("Take " + steps.get() + " steps a day");
}
}
});
} else {
steps.set("0000");
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(1.0f).setDuration(3000);
}
}
public void onClickStepsButton1(View view) {
steps.set("2000");
}
public void onClickStepsButton2(View view) {
steps.set("8000");
}
public void onClickStepsButton3(View view) {
steps.set("10000");
}
public void onClickStepsButton4(View view) {
steps.set("13000");
}
public void onClickSave(View view) {
if ((Integer.valueOf(steps.get()) > 0)) {
if (fragmentGoogleFitBinding.saveButton.getTag() == null) {
GoogleFitDataManager.singletonObject(context).buildFitnessClient(new CallBackGoogleFitClient() {
#Override
public void onResponse(GoogleApiClient googleApiClient) {
localGoogleApiClient = googleApiClient;
if (googleApiClient != null) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.previewImage.setVisibility(View.GONE);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
fragmentGoogleFitBinding.goalProgressLayout.setVisibility(View.VISIBLE);
}
}
});
} else {
if (fragmentGoogleFitBinding.saveButton.getTag().equals("disabled_edit")) {
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(1.0f).setDuration(1000);
enableDisableLayout(true);
fragmentGoogleFitBinding.saveButton.setTag("enabled_edit");
fragmentGoogleFitBinding.saveButton.setText("Save");
} else if (fragmentGoogleFitBinding.saveButton.getTag().equals("enabled_edit")) {
new VerifyDataTask().execute(localGoogleApiClient);
fragmentGoogleFitBinding.setGoalLayout.animate().alpha(0.2f).setDuration(1000);
enableDisableLayout(false);
fragmentGoogleFitBinding.saveButton.setText("Edit");
fragmentGoogleFitBinding.saveButton.setTag("disabled_edit");
}
}
fragmentGoogleFitBinding.goalText.setText("Take " + steps.get() + " steps a day");
} else
Toast.makeText(context, "Please Select Steps", Toast.LENGTH_SHORT).show();
}
protected void renderStepsProgress(int stepsTaken) {
saveDailyStepsInSharedPref(steps.get());
int percentage = (int) (((double) stepsTaken / (double) Integer.valueOf(steps.get())) * 100);
if (percentage > 100) {
percentage = 100;
}
fragmentGoogleFitBinding.waveLoadingView.setCenterTitle(String.valueOf(percentage) + " %");
fragmentGoogleFitBinding.waveLoadingView.setProgressValue(percentage);
fragmentGoogleFitBinding.stepsTakenText.setText("You have taken " + String.valueOf(stepsTaken) + " steps today");
}
private void enableDisableLayout(Boolean visibility) {
View child;
for (int i = 0; i < fragmentGoogleFitBinding.stepButtonLayout1.getChildCount(); i++) {
child = fragmentGoogleFitBinding.stepButtonLayout1.getChildAt(i);
child.setEnabled(visibility);
}
for (int i = 0; i < fragmentGoogleFitBinding.stepButtonLayout2.getChildCount(); i++) {
child = fragmentGoogleFitBinding.stepButtonLayout2.getChildAt(i);
child.setEnabled(visibility);
}
}
private void saveDailyStepsInSharedPref(String dailySteps) {
SharedPreferences.Editor editor = context.getSharedPreferences("dailySteps", MODE_PRIVATE).edit();
editor.putString("daily_steps", dailySteps);
editor.apply();
}
private class VerifyDataTask extends AsyncTask<GoogleApiClient, Void, Integer> {
#Override
protected Integer doInBackground(GoogleApiClient... params) {
int total = 0;
PendingResult<DailyTotalResult> result = Fitness.HistoryApi.readDailyTotal(params[0], DataType.TYPE_STEP_COUNT_DELTA);
DailyTotalResult totalResult = result.await(30, TimeUnit.SECONDS);
if (totalResult.getStatus().isSuccess()) {
DataSet totalSet = totalResult.getTotal();
total = totalSet.isEmpty()
? 0
: totalSet.getDataPoints().get(0).getValue(Field.FIELD_STEPS).asInt();
} else {
Log.d("steps_count_error", "There was a problem getting the step count!!");
}
return total;
}
protected void onPostExecute(Integer result) {
renderStepsProgress(result);
}
}
}
GoogleFitDataManager.java
package com.example.mudasirrao.mvvm.DataManager;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;
import com.example.mudasirrao.mvvm.CallBacks.CallBackGoogleFitClient;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.FitnessStatusCodes;
import com.google.android.gms.fitness.data.DataType;
import static com.bumptech.glide.gifdecoder.GifHeaderParser.TAG;
public class GoogleFitDataManager {
private static GoogleFitDataManager googleFitDataManager;
private GoogleApiClient googleApiClient = null;
private Context context;
public GoogleFitDataManager(Context context) {
this.context = context;
}
public static GoogleFitDataManager singletonObject(Context context) {
if (googleFitDataManager == null) {
googleFitDataManager = new GoogleFitDataManager(context);
}
return googleFitDataManager;
}
public void buildFitnessClient(final CallBackGoogleFitClient callBackGoogleFitClient) {
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(Fitness.HISTORY_API)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.CONFIG_API)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(#Nullable Bundle bundle) {
subscribeGoogleFit(googleApiClient);
callBackGoogleFitClient.onResponse(googleApiClient);
}
#Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Toast.makeText(context, "Connection lost. Cause: Network Lost.", Toast.LENGTH_SHORT).show();
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(context, "Connection lost. Reason: Service Disconnected", Toast.LENGTH_SHORT).show();
}
}
}
)
.enableAutoManage((FragmentActivity) context, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("TAG", "Google Play services connection failed. Cause: " + result.toString());
Toast.makeText(context, "Exception while connecting to Google Play services: " + result.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
})
.build();
} else {
subscribeGoogleFit(googleApiClient);
callBackGoogleFitClient.onResponse(googleApiClient);
}
}
public void subscribeGoogleFit(GoogleApiClient client) {
Fitness.RecordingApi.subscribe(client, DataType.TYPE_STEP_COUNT_DELTA)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
if (status.getStatusCode() == FitnessStatusCodes.SUCCESS_ALREADY_SUBSCRIBED) {
Log.i(TAG, "Existing subscription for activity detected.");
} else {
Log.i(TAG, "Successfully subscribed!");
}
} else {
Log.i(TAG, "There was a problem subscribing.");
}
}
});
}
}
What I was doing that I was creating the static object of the class in which I was making the googlefit client. In this case, when I exit the Activity, the object was not destroying and googlefit client was getting disconnected due to the enableAutoManage in onDestroy of the fragment. And as per my checks, I was not connecting to the googleFit client again.
I removed the object as static and now I stick the API client class object with the life cycle of the activity in which my fragment resides. Also I removed enableAutoManage and now connecting and disconnecting the API client by myself.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
How can I have an android app that plays a certain noise or sound at a certain time every day?
So far my code consists of a button that will play the noise upon click.
you have to create service
and in the service you play th song from the asset folder every 10:00 AM for example ..
the service will look like this :
MyService.java
import android.app.Service;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.format.Time;
import android.widget.Switch;
import android.widget.Toast;
import java.io.IOException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
private int Annee;
private int Mois;
private int Jour;
private int Heure;
private int Minute;
boolean afficher=true;
private Handler customHandler = new Handler();
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Non implementé");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onStart(Intent intent, int startId) {
Toast.makeText(this,"Service demarré",Toast.LENGTH_LONG).show();
customHandler.postDelayed(updateTimerThread, 3000 );
super.onStart(intent, startId);
}
#Override
public void onDestroy() {
onStop();
Toast.makeText(this,"Service arrété",Toast.LENGTH_LONG).show();
customHandler.removeCallbacks(updateTimerThread);
super.onDestroy();
}
public void onStop(){
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
final Calendar cal = Calendar.getInstance();
Annee = cal.get(Calendar.YEAR);
Mois = cal.get(Calendar.MONTH)%12+1;
Jour = cal.get(Calendar.DAY_OF_MONTH);
Heure=cal.get(Calendar.HOUR_OF_DAY)%24+1;
if(Heure==24)Heure=0;
Minute=cal.get(Calendar.MINUTE);
String min=Integer.toString(Minute);
String heure=Integer.toString(Heure);
String h=heure+":"+min;
java.text.SimpleDateFormat simpleTimeFormat = new java.text.SimpleDateFormat("HH:mm");
String h2 = null;
try {
h2 = simpleTimeFormat.format(simpleTimeFormat.parse(h));
} catch (ParseException e) {
e.printStackTrace();
}
String a, m, j;
j = Integer.toString(Jour);
m = Integer.toString(Mois);
a = Integer.toString(Annee);
String d = j + "/" + m + "/" + a;
java.text.SimpleDateFormat simpleDateFormat = new java.text.SimpleDateFormat("dd/MM/yyyy");
String d2 = null;
try {
d2 = simpleDateFormat.format(simpleDateFormat.parse(d));
} catch (ParseException e) {
e.printStackTrace();
}
if (h2.equals("10:00")) {
if (afficher){
Intent intent =new Intent(getBaseContext(),AlertD.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("Cle",cur.getString(0));
getApplication().startActivity(intent);
afficher=false;}
}}
customHandler.postDelayed(this , 3000 );
};
}
bootCompleted.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
/**
* Created by Mechalikh on 21/12/2014.
*/
public class BootCompleted extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)){
Intent serviceIntent= new Intent(context,MyService.class);
context.startService(serviceIntent);
}
}
}
alertD.java (the alarm dialog)
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class AlertD extends Activity {
MediaPlayer m;
public static String cle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
m=new MediaPlayer();
cle =getIntent().getStringExtra("Cle");
final AlertDialog alertDialog =new AlertDialog.Builder(this).create();
alertDialog.setTitle("Votre rendez-vous");
alertDialog.setMessage("Vous avez un rendez-vous dans UNE HEURE !");
alertDialog.setButton("Arréter", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
m.stop();
AlertD.super.onBackPressed();
}
});
alertDialog.show();
Alarme();
}
private void Alarme() {
try {
if (m.isPlaying()) {
m.stop();
m.release();
m = new MediaPlayer();
}
AssetFileDescriptor descriptor = getAssets().openFd("Alarm.mp3");
m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
m.prepare();
m.setVolume(1f, 1f);
m.setLooping(true);
m.start();
}catch (Exception e){
e.printStackTrace();
}
}
}
for more see this tutorial
http://blog.vogella.com/2011/12/11/automatically-starting-services-in-android-after-booting/
Use alarm manager and schedule a repeating alarm .
Check this demo on repeating alarm schedule :
https://developer.android.com/training/scheduling/alarms.html
Use the Alarm Manager and set an inexact repeating alarm at your time of choice.
I am trying to access a method from a java class by a another java class. I have created the object of the class and import the class into my java class but i am not able to access it my code.
package com.example.musicplayer;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import android.R.string;
import android.app.ListActivity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.provider.MediaStore.Audio.Playlists;
import android.test.suitebuilder.TestSuiteBuilder.FailedToCreateTests;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ListActivity {
public static final String MEDIA_PATH = new String("/sdcard/");
private List<String> songs = new ArrayList<String>();
public MediaPlayer mp = new MediaPlayer();
private int currentPosition = 0;
public MediaPlayer getmp(){
return mp;
}
public void setmp(MediaPlayer mp){
this.mp = mp;
}
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.activity_main);
updateSongList();
}
private void updateSongList() {
// TODO Auto-generated method stub
File home = new File(MEDIA_PATH);
if(home.listFiles(new Mp3Filter()).length > 0){
for(File file: home.listFiles(new Mp3Filter())){
songs.add(file.getName());
}
}
ArrayAdapter<String> songList = new ArrayAdapter<String>(this, R.layout.song_item, songs);
setListAdapter(songList);
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id){
currentPosition = position;
playSong(MEDIA_PATH + songs.get(position));
//Toast.makeText(getApplicationContext(), songs.get(position).toString(), Toast.LENGTH_SHORT).show();
final String songName = songs.get(position).toString();
//final TextView textchange = (TextView) v.findViewById(R.id.current_song_name);
Intent in = new Intent(this, current_song.class);
in.putExtra("song_name", songName);
startActivity(in);
//Toast.makeText(getApplicationContext(), "End of Song List", Toast.LENGTH_SHORT).show();
//textchange.setText(songName);
}
private void playSong(String songPath) {
// TODO Auto-generated method stub
try{
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
mp.setOnCompletionListener(new OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
auto_nextSong();
}
});
}
catch (Exception e) {
// TODO: handle exception
}
}
public void pause(){
mp.pause();
}
public void stop(){
mp.stop();
}
public void next(){
Toast.makeText(getApplicationContext(), "In Next()", Toast.LENGTH_SHORT).show();
if(currentPosition < songs.size()){
currentPosition = currentPosition + 1;
playSong(MEDIA_PATH + songs.get(currentPosition));
}
}
public void prv(){
if(currentPosition > songs.size()){
currentPosition = currentPosition - 1;
playSong(MEDIA_PATH + songs.get(currentPosition));
}
}
private void auto_nextSong() {
// TODO Auto-generated method stub
if(++currentPosition >= songs.size()){
currentPosition = 0;
Toast.makeText(getApplicationContext(), "End of Song List", Toast.LENGTH_SHORT).show();
}
else{
playSong(MEDIA_PATH + songs.get(currentPosition));
Toast.makeText(getApplicationContext(), "Next Song", Toast.LENGTH_SHORT).show();
}
}
}
from the above class i am trying to access pause() and stop()
this is my class where i am trying to access
package com.example.musicplayer;
import com.example.musicplayer.MainActivity;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class current_song extends Activity implements OnClickListener{
public MainActivity ma;
protected void onCreate(Bundle icicle, MainActivity ma) {
Bundle extra = getIntent().getExtras();
super.onCreate(icicle);
setContentView(R.layout.songplay_page);
if(extra != null){
String song_name = extra.getString("song_name");
TextView textchange = (TextView)findViewById(R.id.current_song_name);
textchange.setText(song_name);
textchange.setSelected(true);
}
//MainActivity ma = ((MainActivity)getApplicationContext());
//MediaPlayer mp = ma.getmp();
this.ma = ma;
Button btn_pause = (Button)findViewById(R.id.pause_btn);
btn_pause.setOnClickListener(this);
Button btn_next = (Button)findViewById(R.id.next_btn);
btn_next.setOnClickListener(this);
Button btn_prv = (Button)findViewById(R.id.prv_btn);
btn_prv.setOnClickListener(this);
Button btn_stop = (Button)findViewById(R.id.stop_btn);
btn_stop.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//Toast.makeText(getApplicationContext(), "In Onclick ()", Toast.LENGTH_SHORT).show();
switch(v.getId())
{
case R.id.pause_btn:
((MainActivity)ma).pause();
break;
case R.id.next_btn:
//ma.next();
break;
case R.id.prv_btn:
//ma.prv();
break;
case R.id.stop_btn:
((MainActivity)ma).stop();
break;
}
}
}
The concept is that i want to stop, pause the music which is playing. If my logic i wrong please guide me how to do it else please help me how to control my current music in Current music java class.
Please, move all your music playing code into Service. Activities don't work that way.
Consider the following:
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
http://developer.android.com/reference/android/app/Service.html
I think You are new to android but no problem: See you can not call the functions of activity from any other class like this (Object.method();)
SO For this type of handling You Should Create a inner Handler class which extends Handler inside your MainActivity. and override onHandle(message msg){} method of it.
And When You start current_song activity pass this handler object in the intent.
And when you want to perform any task from your MainActivity (like stop, pause), pass messages through that handler like object.sendmessage(new msgObject("stop"));
And inside you onHandle() method call your stop or pause methods through diffrentiating command received from the message object.
like if(message's content == stop) MainActivity.this.stop();
I've made an apache thrift server and I have a service which contains several functions.
I'm trying to figure out what is the best way to make calls to the remote server from my android application.
My problem is that I can't make calls from the MainActivity thread (the main thread) - and I need to use most of the remote functions in my main activity methods.
I tried to make a static class with a static member called "Server" equals to the server object, and I set it in another thread and then I tried to call it in the main thread (the main activity class) - but I had errors because of jumping from one thread to another..
To be more specified I want something like that:
public class MainActivity extends Activity {
private service.Client myService;
#Override
protected void onCreate(Bundle savedInstanceState) {
..
... Some stuff that define myService (In a new thread ofcourse) ...
}
...
private void MyFunc1() {
myService.Method1();
}
private void MyFunc2() {
myService.Method2();
}
private void MyFunc3() {
myService.Method3();
}
}
I've got a library for talking to REST APIs. Feel free to slice, dice, and re-use: https://github.com/nedwidek/Android-Rest-API
The code is BSD or GPL.
Here's how I use what I have (I've trimmed MainActivity a bit, hopefully not too much):
package com.hatterassoftware.voterguide.api;
import java.util.HashMap;
public class GoogleCivicApi {
protected final String baseUrl = "https://www.googleapis.com/civicinfo/us_v1/";
protected String apiKey = "AIzaSyBZIP5uY_fMF35SVVrytpKgHtppBbj8J0I";
public static final String DATE_FORMAT = "yyyy-MM-dd";
protected static HashMap<String, String> headers;
static {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
}
public String createUrl(String uri, HashMap<String, String> params) {
String url = baseUrl + uri + "?key=" + apiKey;
if (params != null) {
for (String hashKey: params.keySet()) {
url += hashKey + "=" + params.get(hashKey) + "&";
}
url = url.substring(0, url.length());
}
return url;
}
}
package com.hatterassoftware.voterguide.api;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hatterassoftware.restapi.GetTask;
import com.hatterassoftware.restapi.HttpReturn;
import com.hatterassoftware.restapi.RestCallback;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.models.Election;
public class ElectionsQuery extends GoogleCivicApi implements RestCallback {
GetTask getTask;
ElectionCallback callback;
final String TAG = "ElectionQuery";
public ElectionsQuery(ElectionCallback callback) {
String url = this.createUrl("elections", null);
this.callback = callback;
Log.d(TAG, "Creating and executing task for: " + url);
getTask = new GetTask(url, this, null, null, null);
getTask.execute();
}
#Override
public void onPostSuccess() {
Log.d(TAG, "onPostSuccess entered");
}
#Override
public void onTaskComplete(HttpReturn httpReturn) {
Log.d(TAG, "onTaskComplete entered");
Log.d(TAG, "httpReturn.status = " + httpReturn.status);
if (httpReturn.content != null) Log.d(TAG, httpReturn.content);
if (httpReturn.restException != null) Log.d(TAG, "Exception in httpReturn", httpReturn.restException);
JsonParser parser = new JsonParser();
JsonElement electionArrayJson = ((JsonObject)parser.parse(httpReturn.content)).get("elections");
Log.d(TAG, electionArrayJson.toString());
Gson gson = new GsonBuilder().setDateFormat(GoogleCivicApi.DATE_FORMAT).create();
Election[] elections = gson.fromJson(electionArrayJson.toString(), Election[].class);
callback.retrievedElection(elections);
}
}
package com.hatterassoftware.voterguide;
import java.util.Calendar;
import java.util.List;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.hatterassoftware.voterguide.api.ElectionsQuery;
import com.hatterassoftware.voterguide.api.VoterInfoQuery;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.callbacks.VoterInfoCallback;
import com.hatterassoftware.voterguide.api.models.Election;
import com.hatterassoftware.voterguide.api.models.VoterInfo;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends SherlockFragmentActivity implements ElectionCallback, VoterInfoCallback {
private ProgressBar mProgressBar;
public Button submit;
public Spinner state;
public Spinner election;
public EditText address;
public EditText city;
public EditText zip;
private int count=0;
private Object lock = new Object();
private static final String TAG = "MainActivity";
public static final String VOTER_INFO = "com.hatterassoftware.voterguide.VOTER_INFO";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.home_progressBar);
Resources res = getResources();
SharedPreferences mPrefs = getApplicationSharedPreferences();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
try {
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
gpsButton.setClickable(false);
}
} catch(Exception e) {
Log.d(TAG, e.getMessage(), e);
gpsButton.setClickable(false);
gpsButton.setEnabled(false);
}
submit = (Button) findViewById(R.id.submit);
submit.setClickable(false);
submit.setEnabled(false);
state = (Spinner) findViewById(R.id.state);
election = (Spinner) findViewById(R.id.election);
address = (EditText) findViewById(R.id.streetAdress);
city = (EditText) findViewById(R.id.city);
zip = (EditText) findViewById(R.id.zip);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doSubmit();
}
});
gpsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doLocate();
}
});
// Let's check for network connectivity before we get down to business.
if (Utils.isNetworkAvailable(this, true)) {
// Show the disclaimer on first run.
if(mPrefs.getBoolean("firstRun", true)) {
AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setCancelable(false);
alert.setTitle(res.getString(R.string.welcome));
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView alertContents = (TextView) layout.findViewById(R.id.custom_dialog_text);
alertContents.setMovementMethod(LinkMovementMethod.getInstance());
alertContents.setText(Html.fromHtml(res.getString(R.string.welcome_dialog_text)));
alert.setView(alertContents);
alert.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences mPrefs = getApplicationSharedPreferences();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean("firstRun", false);
editor.commit();
dialog.dismiss();
retrieveElections();
}
});
alert.show();
} else {
retrieveElections();
}
}
}
#Override
public void onResume() {
super.onResume();
// Let's check for network connectivity before we get down to business.
Utils.isNetworkAvailable(this, true);
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!(manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
Toast.makeText(this, "GPS is not available", 2).show();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
gpsButton.setClickable(false);
}
}
public SharedPreferences getApplicationSharedPreferences() {
Context mContext = this.getApplicationContext();
return mContext.getSharedPreferences("com.hatterassoftware.voterguide", MODE_PRIVATE);
}
private void showSpinner() {
synchronized(lock) {
count++;
mProgressBar.setVisibility(View.VISIBLE);
}
}
private void hideSpinner() {
synchronized(lock) {
count--;
if(count < 0) { // Somehow we're trying to hide it more times than we've shown it.
count=0;
}
if (count == 0) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
}
public void retrieveElections() {
Log.d(TAG, "Retrieving the elections");
showSpinner();
ElectionsQuery query = new ElectionsQuery(this);
}
#Override
public void retrievedElection(Election... elections) {
Log.d(TAG, "Retrieved the elections");
hideSpinner();
for (int i=0; i<elections.length; i++) {
Log.d(TAG, elections[i].toString());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, elections);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = (Spinner) this.findViewById(R.id.election);
spinner.setAdapter(arrayAdapter);
}
}