2

I have a problem with a quite simple Android app that I'm deveolping. It's something like a football score board. The activity consists of 3 fragments (2 for the team goals and 1 for the timer) and I have a service to perform the countdown. It seems to work, but when I rotate the screen, the countdown continue but it doesn't update my textview (called "timer"). I'm posting the code of the fragment, the activity and the service. I'm sorry if sometimes the code is a bit messy.

public class BoardActivity extends FragmentActivity implements BoardActivityCallback{

    public static final String TAG = "BoardActivity";
    public static final boolean D = true;

    public static final String TEAM_NAME1 = "TEAM_NAME1";
    public static final String TEAM_SCORE1 = "TEAM_SCORE1";
    public static final String TEAM_NAME2 = "TEAM_NAME2";
    public static final String TEAM_SCORE2 = "TEAM_SCORE2";
    public static final String HALF_TIME = "HALF_TIME";
    public static final String HALF_NUMBER = "HALF_NUMBER";
    public static final String OUT_TIME = "OUT_TIME";
    public static final String ROBOTS_NUMBER = "ROBOTS_NUMBER";

    public static final int CREATE_AND_START_TIMER = 0;
    public static final int GET_ACTIVITY_MESSENGER = 55;

    private TeamFragment teamFragment1;
    private TeamFragment teamFragment2;
    private TimerFragment timerFragment;
    private boolean isPlaying;

    //private TimeService timeService;
    private boolean isTimeServiceBound;
    private Messenger fromService = new Messenger(new MessagesFromTimeServiceHandler());
    private Messenger toService;
    private Message message;



    private ServiceConnection timeServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //timeService = ((TimeService.ServiceBinder)service).getService();
            //Toast.makeText(BoardActivity.this, "Service connected", Toast.LENGTH_SHORT).show();
            toService = new Messenger(service);
            Message msg = new Message();
            msg.what = GET_ACTIVITY_MESSENGER;
            try {
                toService.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //timeService = null;
            //Toast.makeText(BoardActivity.this, "Service disconnected", Toast.LENGTH_SHORT).show();
            toService = null;
        }
    };

    private void doBindTimeService(){
        Intent bindIntet = new Intent(BoardActivity.this,TimeService.class);
        //bindIntet.putExtra("Messenger", fromService);
        //bindIntet.putExtra("Halftime",getIntent().getStringExtra(HALF_TIME));
        bindService(bindIntet, timeServiceConnection, Context.BIND_AUTO_CREATE);
        //bindService(new Intent(BoardActivity.this,TimeService.class), timeServiceConnection, Context.BIND_AUTO_CREATE);
        isTimeServiceBound = true;
    }

    private void doUnbindTimeService(){
        if(isTimeServiceBound){
            unbindService(timeServiceConnection);
            isTimeServiceBound = false;
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.board);

        if(D) Log.d(TAG,"--- onCreate ---");


        teamFragment1 = (TeamFragment) getSupportFragmentManager().findFragmentById(R.id.teamFragment1);
        teamFragment2 = (TeamFragment) getSupportFragmentManager().findFragmentById(R.id.teamFragment2);
        timerFragment = (TimerFragment) getSupportFragmentManager().findFragmentById(R.id.timerFragment);
        Intent callingIntent = getIntent();

        if(teamFragment1 != null && teamFragment2 != null && timerFragment != null && callingIntent != null){

            teamFragment1.setColor(getResources().getColor(R.color.yellow));
            teamFragment2.setColor(getResources().getColor(R.color.blue));

            teamFragment1.setName(callingIntent.getStringExtra(TEAM_NAME1));
            teamFragment2.setName(callingIntent.getStringExtra(TEAM_NAME2));

            teamFragment1.setOutTime(callingIntent.getStringExtra(OUT_TIME));
            teamFragment2.setOutTime(callingIntent.getStringExtra(OUT_TIME));

//            timerFragment.setHalfTime(callingIntent.getStringExtra(HALF_TIME));
//            timerFragment.setHalfNumber(callingIntent.getStringExtra(HALF_NUMBER));

            try{
                teamFragment1.setScore(Integer.parseInt(callingIntent.getStringExtra(TEAM_SCORE1)));
                teamFragment2.setScore(Integer.parseInt(callingIntent.getStringExtra(TEAM_SCORE2)));

                String robotsNumberString = callingIntent.getStringExtra(ROBOTS_NUMBER);
                int robotsNumber = Integer.parseInt(robotsNumberString.substring(0, robotsNumberString.indexOf(' ')));
                teamFragment1.setRobotsNumber(robotsNumber);
                teamFragment2.setRobotsNumber(robotsNumber);

            }catch(NumberFormatException nfe){
                Log.e(TAG,nfe.getMessage());
            }
        }


    }

    @Override
    protected void onStart() {
        super.onStart();
        doBindTimeService();
        if(D) Log.d(TAG,"--- onStart ---");
    }

    @Override
    protected void onPause() {
        super.onPause();

        if(D) Log.d(TAG,"--- onPause ---");
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(D) Log.d(TAG,"--- onResume ---");
    }

    @Override
    protected void onStop() {
        super.onStop();
        doUnbindTimeService();
        if(D) Log.d(TAG,"--- onStop ---");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if(D) Log.d(TAG,"--- onDestroy ---");
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if(D) Log.d(TAG,"--- onConfigurationChanged ---");
    }

    @Override
    public void onSetPlaying(boolean isPlaying){
        this.isPlaying = isPlaying;
    }

    @Override
    public void onGoalScored() {
        if(teamFragment1 != null && teamFragment2 != null){
            teamFragment1.allRobotsInside();
            teamFragment2.allRobotsInside();
        }
    }

    private void notifyToService(int what, String obj){
        message = Message.obtain(null, what, obj);
        try {
            toService.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }



    @Override
    public void startTimer(){
        notifyToService(CREATE_AND_START_TIMER,getIntent().getStringExtra(HALF_TIME));
    }


    class MessagesFromTimeServiceHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
                case TimeService.CREATED_TIMER:
                    timerFragment.displayTime(TimerManager.timerFormat(Long.valueOf(msg.obj.toString())));
                    teamFragment1.setEditable(false);
                    teamFragment2.setEditable(false);
                    Log.d(TAG,"Timer creato");
                    break;
                case TimeService.START_TIMER:
                    teamFragment1.setEditable(true);
                    teamFragment2.setEditable(true);
                    //timeService.showTimerNotification();
                    break;
                case TimeService.UPDATE_TIMER:
                    Log.d(TAG,"Ricevuto dal service: "+TimerManager.timerFormat(Long.valueOf(msg.obj.toString())));
                    timerFragment.displayTime(TimerManager.timerFormat(Long.valueOf(msg.obj.toString())));
                    break;
                case TimeService.PAUSE_TIMER:
                    teamFragment1.setEditable(false);
                    teamFragment2.setEditable(false);
                    //timeService.cancelTimerNotification();
                    break;
                case TimeService.FINISH_TIMER:
                    Log.d(TAG,"Timer finito");
                    teamFragment1.setEditable(false);
                    teamFragment2.setEditable(false);
                    //timeService.cancelTimerNotification();
                    break;
                case 55:
                    Log.d(TAG,"Ricevuto dal Service: "+msg.obj.toString());
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
}


public class TimerFragment extends Fragment{

    private static final String TAG = "TimerFragment";
    private static final boolean D = true;

    private TextView timer;
    private TextView currentHalf;


    private BoardActivityCallback boardActivityCallback;


    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            boardActivityCallback = (BoardActivityCallback) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement BoardActivityCallback");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.timer,container,false);

        if(D) Log.d(TAG,"--- onCreateView ---");

        timer = (TextView)view.findViewById(R.id.timer);
        currentHalf = (TextView)view.findViewById(R.id.currentHalf);

        if(D) Log.d(TAG,"timer: "+timer.toString());

        timer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                boardActivityCallback.startTimer();

            }
        });

        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStart() {
        super.onStart();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onViewStateRestored(Bundle savedInstanceState) {
        super.onViewStateRestored(savedInstanceState);
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onResume() {
        super.onResume();
    }


    public void setHalfNumber(String halfNumber){
        currentHalf.setText(halfNumber);
    }

    public void displayTime(String time){
        timer.setText(time);
    }

}

public class TimeService extends Service {

    private static final String TAG = "TimeService";
    private static final boolean D = true;

    private final IBinder serviceBinder = new ServiceBinder();
    private NotificationManager notificationManager;

    private static final int TIMER_NOTIFICATION = 1;

    private Messenger toActivity;
    private Message message;

    public static final int CREATED_TIMER = 0;
    public static final int START_TIMER = 1;
    public static final int UPDATE_TIMER = 2;
    public static final int PAUSE_TIMER = 3;
    public static final int FINISH_TIMER = 4;


    private CountDownTimer timer;

    private Messenger fromActivity = new Messenger(new IncomingHandler());

    public class ServiceBinder extends Binder {
        TimeService getService(){
            return TimeService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {

        if(D) Log.d(TAG,"--- onBind ---");

        //toActivity = intent.getParcelableExtra("Messenger");

        //timer = new CountDownTimer(TimerManager.minSecToMillis(intent.getStringExtra("Halftime")));


        //return serviceBinder;
        return fromActivity.getBinder();
    }

    @Override
    public void onCreate() {
        super.onCreate();

        if(D) Log.d(TAG,"--- onCreate ---");

        notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(D) Log.d(TAG,"--- onStartCommand ---");

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if(D) Log.d(TAG,"--- onDestroy ---");

        cancelTimerNotification();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        if(D) Log.d(TAG,"--- onUnbind ---");
        return super.onUnbind(intent);

    }

    @Override
    public void onRebind(Intent intent) {
        super.onRebind(intent);
        if(D) Log.d(TAG,"--- onRebind ---");
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if(D) Log.d(TAG,"--- onConfigurationChanged ---");
    }

    public void showTimerNotification(){
//        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,BoardActivity.class), 0, null);


//        Notification notification = new Notification.Builder(this)
//                .setContentTitle(getResources().getString(R.string.app_name))
//                .setContentText("The teams are playing a match")
//                .setContentIntent(pendingIntent)
//                .setSmallIcon(R.drawable.ic_launcher)
//                .setWhen(0)
//                .build();

        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle("Titolo")
                .setContentText("Contenuto")
                .setWhen(0);

        NotificationCompat.InboxStyle inboxStyle =  new NotificationCompat.InboxStyle();
        String[] events = {"Line1","Line2","Line3","Line4"};
        inboxStyle.setBigContentTitle("Dettagli:");
        inboxStyle.setBigContentTitle("RoboSoccer Board");

        for (int i=0; i < events.length; i++) {

            inboxStyle.addLine(events[i]);
        }

        mBuilder.setStyle(inboxStyle);

        Notification notification = mBuilder.build();

        notification.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT;

        notificationManager.notify(TIMER_NOTIFICATION, notification);
    }

    public void cancelTimerNotification(){
        if(notificationManager != null){
            notificationManager.cancel(TIMER_NOTIFICATION);
        }
    }

    private void notifyToBoard(int what, String obj){
        message = Message.obtain(null, what, obj);
        try {
            toActivity.send(message);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    public void countDown(){
        timer.startTimer();
    }

    class CountDownTimer extends Thread{

        private long actualMillis;
        private boolean isCountingDown;

        public CountDownTimer(long millis){
            actualMillis = millis;
            isCountingDown = false;
            notifyToBoard(CREATED_TIMER,String.valueOf(actualMillis));
        }

        @Override
        public void run(){
            notifyToBoard(START_TIMER,String.valueOf(actualMillis));
            try{
                do{
                    isCountingDown = true;
                    actualMillis -= 1000;
                    notifyToBoard(UPDATE_TIMER,String.valueOf(actualMillis));
                    Thread.sleep(1000);
                }while (isCountingDown && actualMillis > 0);
            }catch (InterruptedException ie){
                isCountingDown = false;
            }
            isCountingDown = false;
            notifyToBoard(FINISH_TIMER,String.valueOf(actualMillis));
        }


        public void startTimer(){
            if(!isCountingDown){
                this.start();
            }
        }

        public void pauseTimer(){
            this.interrupt();
            notifyToBoard(PAUSE_TIMER,String.valueOf(actualMillis));
        }

        public void stopTimer(){
            this.interrupt();
            actualMillis = 0;
        }

    }

    class IncomingHandler extends Handler {

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case BoardActivity.GET_ACTIVITY_MESSENGER:
                    toActivity = msg.replyTo;
                    break;
                case BoardActivity.CREATE_AND_START_TIMER:
                    //Log.d(TAG,"Ricevuto dall'Activity: "+msg.obj.toString());
                    //notifyToBoard(55,"Timer avviato");
                    timer = new CountDownTimer(TimerManager.minSecToMillis(msg.obj.toString()));
                    timer.startTimer();
                    break;
                default:
                    super.handleMessage(msg);
            }
        }
    }
}
codeblender
  • 21
  • 1
  • 3

0 Answers0