我正在开发的一个非常简单的 Android 应用程序有问题。这有点像足球记分牌。该活动由 3 个片段组成(2 个用于团队目标,1 个用于计时器),我有一个服务来执行倒计时。它似乎有效,但是当我旋转屏幕时,倒计时继续但它不会更新我的文本视图(称为“计时器”)。我正在发布片段、活动和服务的代码。如果有时代码有点乱,我很抱歉。
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);
}
}
}
}