2015-01-06 3 views
0

Я создаю приложение, в котором есть кнопка изображения, которая запускает Сервис при нажатии. Служба содержит обработчик, который я использую в качестве 24-часового таймера. Когда Служба запущена, кнопка отключена, поэтому ее нельзя нажать снова. Затем, когда время увеличивается, кнопка снова включается. Все это отлично работает, пока приложение не будет полностью закрыто. Если приложение полностью закрыто, Служба продолжает работать так, как должна, но существует проблема с BroadcastReceiver. Если приложение закрыто, а затем снова открыто, кнопка запуска службы может быть нажата, даже если служба уже запущена. Я не уверен, почему кнопка включена, когда приложение снова открывается, хотя служба все еще работает.BroadcastReceiver from Service не работает правильно, когда приложение закрыто

Вот код для моей службы:

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 класс

Вот код для кнопки, которая принимает логическое значение из BroadcastReceiver:

//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

Могу ли я это сделать и все еще работать, когда приложение полностью закрыто? И возможно ли, чтобы я сохранил это, как у меня? – sboehnke

+0

AlarmManager будет запускать будильник каждые 24 часа (или на любой другой интервал), даже если ваше приложение полностью уничтожено системой. В отличие от Службы, которая может быть убита и больше не будет стрелять. Поэтому, если вы держите его на своем пути, вы не можете быть уверены, что будильник погаснет. С AlarmManager вы всегда уверены. –

Смежные вопросы