我有一个Android服务,我不希望手机自动禁用服务。 因此,我尝试将通知发送到通知栏。 当我尝试这样做时,我的HTC Hero重新启动。
我使用以下代码,出了什么问题?它部分复制自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);
}
答案 0 :(得分:3)
好吧,它不应该重新启动,但样本中的代码至少有两个主要错误,并且不会按预期工作。我已经使用Android 1.6模拟器对其进行了测试,只有在以下更改后才能使用它:
mStartForeground.invoke(this, mStartForegroundArgs);
更改为method.invoke(this, args);
mStartForeground = mStopForeground = null;
之后删除返回并将其放在mStopForeground = getClass().getMethod("stopForeground", mStopForegroundSignature);
之后将解决此问题。
醇>
更新:Google似乎已经修复了the sample,它应该可以正常使用。
答案 1 :(得分: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};