2015-01-06 50 views
0

我正在創建一個應用程序,該應用程序具有單擊時啓動服務的圖像按鈕。該服務包含一個我用作24小時定時器的處理程序。服務啓動時,該按鈕被禁用,因此無法再次單擊。然後當時間到了時,按鈕再次啓用。這一切都很好,直到應用程序完全關閉。如果應用程序完全關閉,則服務會繼續運行,除非BroadcastReceiver存在問題。如果應用程序關閉然後重新打開,即使服務已經運行,也可以單擊啓動服務的按鈕。我不知道爲什麼當應用程序重新打開時啓用該按鈕,即使該服務仍在運行。當應用程序關閉時,來自服務的BroadcastReceiver無法正常工作

這裏是我的服務的代碼:

public class SetupTimerPC1 extends Service 
{ 
Handler handler; 
Database data; 
Intent i, result; 
runGraphics runG; 
int bucketLevel = 1, bucketExpTotal = 0, totalWater = 0, bucketExp = 0; 
float waterAmt = 0; 
int timerCount = 0; 
Notification notify; 
Notification.Builder builder; 
NotificationManager notificationManager; 
PendingIntent pendingIntent; 
@Override 
public IBinder onBind(Intent intent) 
{ 
    return null; 
}//end onBind function 

@Override 
public void onRebind(Intent intent) 
{ 
    super.onRebind(intent); 
}//end onRebing 

@Override 
public boolean onUnbind(Intent intent) 
{ 
    return true; 
}//end onUnbind 

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

    //setup 24 hour timer 
    handler = new Handler(Looper.getMainLooper()); 
    handler.postDelayed(runnable, 2000); //600000 -> wait ten minutes then call runnable 
}//end onCreate function 

private Runnable runnable = new Runnable() 
{ 
    public void run() 
    { 
     //get current bucket exp 
     data = new Database(SetupTimerPC1.this); 
     data.open(); 
     bucketExp = data.getBucketExp(); 
     data.close(); 

     //check experience for current level 
     if (bucketExp < 3000) 
     { 
      bucketLevel = 1; 
     }//end if 
     else if (bucketExp > 3000 && bucketExp < 6000) 
     { 
      bucketLevel = 2; 
     }//end else if 
     else if (bucketExp > 6000 && bucketExp < 9000) 
     { 
      bucketLevel = 3; 
     }//end else if 
     else if (bucketExp > 9000 && bucketExp < 12000) 
     { 
      bucketLevel = 4; 
     }//end else if 
     else if (bucketExp > 12000) 
     { 
      bucketLevel = 5; 
     }//end else if 

     //give resource based on level 
     if (bucketLevel == 1) 
     { 
      waterAmt += .2; 
      bucketExp += 1; 
     }//end if 
     else if (bucketLevel == 2) 
     { 
      waterAmt += .4; 
      bucketExp += 2; 
     }//end else if 
     else if (bucketLevel == 3) 
     { 
      waterAmt += .6; 
      bucketExp += 3; 
     }//end else if 
     else if (bucketLevel == 4) 
     { 
      waterAmt += .8; 
      bucketExp += 4; 
     }//end else if 
     else if (bucketLevel == 5) 
     { 
      waterAmt += 1.0; 
      bucketExp += 5; 
     }//end else if 
     timerCount++; 
     if (timerCount < 5)//144 
     { 
      handler.postDelayed(runnable, 2000); //600000 
     }//end if 
     else 
     { 
      //pull data 
      data = new Database(SetupTimerPC1.this); 
      data.open(); 
      bucketExpTotal = data.getBucketExp(); 
      totalWater = data.getWaterAmt(); 
      data.close(); 

      //add new data to old 
      bucketExpTotal += bucketExp; 
      totalWater += (int)waterAmt; 

      //push data 
      data.open(); 
      data.bucketExpEntry(bucketExpTotal); 
      data.waterAmountEntry(totalWater); 
      data.bucketLevelEntry(bucketLevel); 
      data.close(); 

      //send notification that resources have been gained 
      notifyUser(); 

      i.putExtra("polarCap1Stat", true); 
      LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i); 
      handler.removeCallbacks(runnable); 
     }//end else 
    }//end run function 
};//end runnable  

public void notifyUser() 
{ 
    //notify user of resource gain 
    result = new Intent(this, runGraphics.class); 
    pendingIntent = PendingIntent.getActivity(
     SetupTimerPC1.this, 
     0, 
     result, 
     Intent.FLAG_ACTIVITY_NEW_TASK); 

    notify = new Notification.Builder(getApplicationContext()) 
     .setContentTitle("2023: Water Gained") 
     .setContentText("Successfully extracted water.") 
     .setTicker("2023") 
     .setWhen(System.currentTimeMillis()) 
     .setContentIntent(pendingIntent) 
     .setDefaults(Notification.DEFAULT_SOUND) 
     .setAutoCancel(true) 
     .setSmallIcon(R.drawable.alienicon) 
     .build(); 

     notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
     notificationManager.notify(0, notify); 
}//end notifyUser 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) 
{ 
    i = new Intent("polarCap1Status"); 
    i.putExtra("polarCap1Stat", false); 
    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(i); 
    return Service.START_STICKY; 
}//end onStartCommand function 

} //結束SetupTimerPC1類

這裏是從廣播接收器接收的布爾按鈕的代碼:

//setup image buttons 
    polarCap1 = (ImageButton) findViewById(R.id.polarCapButton1); 
    polarCap1.setOnClickListener(new OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      Toast.makeText(getApplicationContext(), "Attempting to Gain Resources", Toast.LENGTH_SHORT).show(); 

      if (polarCap1.isEnabled() && appSound) 
      { 
       water = new SoundPool(2, AudioManager.STREAM_MUSIC, 0); 
       playSound = water.load(runGraphics.this, R.raw.watersound, 1); 

       //play water sound 
       water.setOnLoadCompleteListener(new OnLoadCompleteListener() 
       { 

        @Override 
        public void onLoadComplete(SoundPool soundPool, 
          int sampleId, int status) 
        { 
         water.play(playSound, 1, 1, 0, 0, 1); 
        }//end onLoadComplete 

       });//end setOnLoadCompleteListener 
      }//end if 

      //button cannot be clicked 
      polarCap1.setEnabled(false); 

      //start service for timer 
      startService(new Intent(runGraphics.this, SetupTimerPC1.class)); 

      //stop service for timer 
      //stopService(new Intent(runGraphics.this, SetupTimerPC1.class)); 

      //broadcast receiver to allow button to be clicked again 
      mMessageReceiver1 = new BroadcastReceiver() 
      { 
       @Override 
       public void onReceive(Context context, Intent intent) 
       { 
        clickOnOff1 = intent.getBooleanExtra("polarCap1Stat", false); 
        polarCap1.setEnabled(clickOnOff1); 
        updateScores(); 
       }//end onReceive function 
      }; 
      LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mMessageReceiver1, new IntentFilter("polarCap1Status")); 
     }//end onClick function   
    });//end setOnClickListener 

非常感謝您的幫助。

回答

1

如果你想保持你在做什麼,你可以添加以下代碼,以檢查在的onCreate()isMyServiceRunning(SetupTimerPC1.class)您服務的狀態。如果它正在運行,那麼你可以禁用該按鈕:

private boolean isMyServiceRunning(Class<?> serviceClass) { 
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { 
    if (serviceClass.getName().equals(service.service.getClassName())) { 
     return true; 
    } 
} 
return false; 
} 
1

我認爲它已啓用,因爲您的應用程序重新啓動,沒有服務,沒有任何和最初禁用按鈕。

使用Service作爲24小時計時器的想法不正確,您應該使用AlarmManager來代替並將「警報已設置」狀態保存在Preference中。然後根據保存的首選項啓用/禁用按鈕。

+0

我可以這樣做,並仍然kep它在應用程序已完全關閉時運行嗎?我可以按照我擁有的方式保持它嗎? – sboehnke

+0

即使您的應用程序已被系統完全殺死,AlarmManager也會每隔24小時(或以任何其他時間間隔)觸發警報。與服務不同,它可以被殺死,並且不會再發射任何東西。所以,如果你保持它的方式,你不能確定警報會熄滅。有了AlarmManager,你一定會確定的。 –

相關問題