2016-03-30 18 views
0

我有以下代碼從Service派生,我想在後臺運行該服務。在本課中,我使用SharedPreferences.OnSharedPreferenceChangeListener類來檢查共享首選項是否發生變化,以便重新初始化BroadcastReceiver以在某些定義的時間間隔(如每6小時)運行。但是,當我將主要活動中的顯式共享首選項更改爲3小時時,例如,我需要在3小時(而不是6小時)內運行代碼。下面是Service代碼:如何解決「實際參數<匿名OnSharedPreferenceChangeListener>無法通過方法調用轉換轉換爲上下文」

public class AlarmService extends Service 
{ 
    public Alarm alarm = new Alarm(); 
    public SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 

    public void onCreate() 
    { 
     super.onCreate(); 
     SharedPreferences.OnSharedPreferenceChangeListener spChanged = new 
      SharedPreferences.OnSharedPreferenceChangeListener() { 
       @Override 
       public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, 
                 String key) {      
        // reinitialize the alarm 
        alarm.SetAlarm(this); // ERROR HERE 
       } 
     }; 
     //SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 
     sharedPref.registerOnSharedPreferenceChangeListener(spChanged); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     Log.d("!~!", "Service started."); 
     alarm.SetAlarm(this); 
     return START_STICKY; 
    } 


    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return null; 
    } 
} 

SetAlarm在從BroadcastReceiver派生的類定義,來作爲方法如下:

public void SetAlarm(Context context) 
    { 
     // get the update cylce from the prefences 
     SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); 
     int updateInterval = Integer.parseInt(sharedPref.getString("updateInterval", "24")); 
     Log.d(LOGHEAD, String.format("Alarm set to update every %d hours.", updateInterval)); 


     AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
     Intent intent = new Intent(context, Alarm.class); 
     PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0); 
     am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * updateInterval, pi); // Millisec * Second * Minute 
    } 

但是,當我編譯代碼,我得到以下錯誤:

Error:(33, 26) error: method SetAlarm in class Alarm cannot be applied to given types; 
required: Context 
found: <anonymous OnSharedPreferenceChangeListener> 
reason: actual argument <anonymous OnSharedPreferenceChangeListener> cannot be converted to Context by method invocation conversion 

錯誤發生處的位置標記在上面。我再次得到相關的「語境」,一個概念的錯誤,我仍然無法理解......

我特別的事實感到困惑,低於futher上的代碼調用

alarm.SetAlarm(this); 

工作正常。也許這個問題是因爲使用內部類?

任何想法如何解決這個問題?或修復整個代碼?我已經把實例中的代碼放在一起,並且我不確定這是否是很好的android代碼...

回答

0

在該特定上下文中,this確實指代OnSharedPreferenceChangeListener,如錯誤消息中所示。

this替換爲AlarmService.this以引用外部服務實例,並且應該起作用。

根據您的評論,您還需要初始化onCreate()中的偏好設置。

首隻宣佈喜好

private SharedPreferences sharedPref; 

,然後裏面onCreate()

sharedPref = PreferenceManager.getDefaultSharedPreferences(this); 
+0

已更新答案以解決您的其他問題。 –

+0

實際上並不需要全局sharedPref,但肯定你有正確的想法... – Alex

+0

我明白了。另外需要注意的是,您可能遇到的行爲是[此處]描述的行爲(http:// stackoverflow。com/a/3104265/1435985)關於註冊一個OnSharedPreferenceChangeListener而沒有強調引用它。 –

0

裏面一個聽衆thisOnSharedPreferenceChangeListener對象不延長Context類。您需要將有效的Context對象傳遞給您的setAlarm方法。
但是,當您在onStartCommand中調用setAlarm時,this表示您的AlarmService對象。

如需進一步參考 - 請閱讀Oracle documentation

相關問題