2011-03-28 90 views
1

我有一個android服務,我不希望手機會自動禁用服務。 因此,我嘗試將通知放入通知欄。 當我嘗試這樣做時,我的HTC Hero重新啓動。在android中將服務帶到前臺

我使用下面的代碼,怎麼了?它部分從reference複製。 有沒有一個很好的教程來解釋這個API的工作原理?

private static final Class<?>[] mSetForegroundSignature = new Class[] { 
    boolean.class}; 
private static final Class<?>[] mStartForegroundSignature = new Class[] { 
    int.class, Notification.class}; 
private static final Class<?>[] mStopForegroundSignature = new Class[] { 
    boolean.class}; 

private NotificationManager mNM; 
private Method mSetForeground; 
private Method mStartForeground; 
private Method mStopForeground; 
private Object[] mSetForegroundArgs = new Object[1]; 
private Object[] mStartForegroundArgs = new Object[2]; 
private Object[] mStopForegroundArgs = new Object[1]; 

void invokeMethod(Method method, Object[] args) { 
    try { 
     mStartForeground.invoke(this, mStartForegroundArgs); 
    } catch (InvocationTargetException e) { 
     // Should not happen. 
     Log.w("ApiDemos", "Unable to invoke method", e); 
    } catch (IllegalAccessException e) { 
     // Should not happen. 
     Log.w("ApiDemos", "Unable to invoke method", e); 
    } 
} 

/** 
* This is a wrapper around the new startForeground method, using the older 
* APIs if it is not available. 
*/ 
void startForegroundCompat(int id, Notification notification) { 
    // If we have the new startForeground API, then use it. 
    if (mStartForeground != null) { 
     mStartForegroundArgs[0] = Integer.valueOf(id); 
     mStartForegroundArgs[1] = notification; 
     invokeMethod(mStartForeground, mStartForegroundArgs); 
     return; 
    } 

    // Fall back on the old API. 
    mSetForegroundArgs[0] = Boolean.TRUE; 
    invokeMethod(mSetForeground, mSetForegroundArgs); 
    mNM.notify(id, notification); 
} 

/** 
* This is a wrapper around the new stopForeground method, using the older 
* APIs if it is not available. 
*/ 
void stopForegroundCompat(int id) { 
    // If we have the new stopForeground API, then use it. 
    if (mStopForeground != null) { 
     mStopForegroundArgs[0] = Boolean.TRUE; 
     try { 
      mStopForeground.invoke(this, mStopForegroundArgs); 
     } catch (InvocationTargetException e) { 
      // Should not happen. 
      Log.w("ApiDemos", "Unable to invoke stopForeground", e); 
     } catch (IllegalAccessException e) { 
      // Should not happen. 
      Log.w("ApiDemos", "Unable to invoke stopForeground", e); 
     } 
     return; 
    } 

    // Fall back on the old API. Note to cancel BEFORE changing the 
    // foreground state, since we could be killed at that point. 
    mNM.cancel(id); 
    mSetForegroundArgs[0] = Boolean.FALSE; 
    invokeMethod(mSetForeground, mSetForegroundArgs); 
} 

private void setupNotification(){ 
    mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE); 
    try { 
     mStartForeground = getClass().getMethod("startForeground", 
       mStartForegroundSignature); 
     mStopForeground = getClass().getMethod("stopForeground", 
       mStopForegroundSignature); 
    } catch (NoSuchMethodException e) { 
     // Running on an older platform. 
     mStartForeground = mStopForeground = null; 
     return; 
    } 
    try { 
     mSetForeground = getClass().getMethod("setForeground", 
       mSetForegroundSignature); 
    } catch (NoSuchMethodException e) { 
     throw new IllegalStateException(
       "OS doesn't have Service.startForeground OR Service.setForeground!"); 
    } 

    CharSequence text = getText(R.string.notification_active_text); 
    // Set the icon, scrolling text and timestamp 
    Notification notification = new Notification(R.drawable.icon, text, 
      System.currentTimeMillis()); 
    startForegroundCompat(
      R.string.foreground_service_started, 
      notification); 

} 

回答

3

那麼,它不應該重新啓動,但是從樣本代碼中有至少2個主要的錯誤,並預期將無法正常工作。我已經與Android 1.6模擬器測試,它只有在以下更改爲我工作:

  1. 的InvokeMethod()顯然是錯誤的,因爲它忽略了傳遞的參數,並進行固定的方法調用來代替。 IntelliJ IDEA的容易識別這個問題的解決將是在original sample改變mStartForeground.invoke(this, mStartForegroundArgs);method.invoke(this, args);
  2. 的onCreate()不會初始化mSetForeground在1.6自回報聲明是在第一,而它必須代替在第一個嘗試。嘗試啓動服務時您將獲得NPE。刪除返回mStartForeground = mStopForeground = null;並將其放在mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);後將解決此問題。

UPDATE:看起來像谷歌已經固定the sample,它應該工作正常開箱。

0

谷歌沒有解決這個問題。 什麼對我來說是把它放在開始,而不是他們用什麼:

private static final Class<?>[] mSetForegroundSignature = new Class[] {Boolean.TYPE}; 
private static final Class<?>[] mStartForegroundSignature = new Class[] {Integer.TYPE, Notification.class}; 
private static final Class<?>[] mStopForegroundSignature = new Class[] {Boolean.TYPE};