我想分析从广播接收的意图。因为不同的广播可能有不同的意图。为了评估不同的广播,我想使用这样的switch case
语句:
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case Intent.ACTION_SCREEN_OFF:
//code for this intent
}
}
但是我知道不可能像这样创建一个switch case语句,所以我觉得我需要类似整数值的东西来识别意图,但是我找不到一种从我的意图中获取这样一个值的方法
有人能告诉我如何使用switch case
声明分析不同的意图吗?
修改:适用于else-if
,但我想使用switch-case
答案 0 :(得分:2)
我也想使用switch-case语句。
所以我创建自定义枚举类,其构造函数需要如下所示的意图操作字符串:
(因为枚举可以用于switch-case语句)
enum ACTION {
INVALID("action.invalid"), // action for ignore.
FOO("action.foo"),
BAR("action.bar"),;
private final String action;
ACTION(String action) {
this.action = action;
}
public String getAction() { // to use it for intentFilter.
return action;
}
public static ACTION getEnum(String action) {
for (ACTION act : values()) {
if (act.action.equals(action)) return act;
}
return INVALID; // do not throw exception like IllegalArgumentException or else. throw exception may disturb your code refactoring.
}
// example - just broadcast
public void broadcast(Context ctx, PARAM.Abstract p) { // I will explain PARAM class later.
Intent intent = new Intent();
intent.setAction(action);
p.injectExtras(intent); // see impl below!
ctx.sendBroadcast(intent);
}
// example - use AlarmManager
public void alarm(Context ctx, Date time, PARAM.Abstract p) {
Intent intent = new Intent();
intent.setAction(action);
p.injectExtras(intent); // see impl below!
AlarmManager alarmManager = (AlarmManager) ctx.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, intent, 0);
alarmManager.set(AlarmManager.RTC, time.getTime(), pendingIntent);
}
// of course, you can use ctx.startService, or else.
}
使用示例:
// trigger it.
ACTION.FOO.broadcast(context,new PARAM.Abstract());
...
// receive & handle it.
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
ACTION anEnum = ACTION.getEnum(action);
switch (anEnum) {
case INVALID: // it can be occured by old version's legacy alarm.
Log.w("INVALID action occured:"+action);
break;
case FOO:
// do something for FOO
break;
case BAR:
// do something for FOO
break;
defalut:
Log.d("Unimplement! action:"+action);
break;
}
}
...
// and I recommend below, when register broadcast receiver.
// create this method below of onReceive.
private IntentFilter getIntentFilter() {
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION.FOO.getAction());
filter.addAction(ACTION.BAR.getAction());
return filter;
}
...
// register your receiver like this
BroadcastReceiver my = new MyBroadcastReceiver();
registerReceiver(my, my.getIntentFilter());
解释PARMA.Abstrat
使用enum进行广播很方便
它减少了工作,例如输入代码(} else if(action.equals("blahblah") {
)和声明操作(static final ACTION_FOO="action.foo"
)
但是......当你需要添加一些额外内容来向其他组件发送内容时,你会发现没有办法像ACTION.FOO.broadcastWithParam(p);
那样。即使您在broadcastWithParam()
上实施了FOO
,也无法访问方法broadcastWithParam()
。因为这就是枚举的工作原理。(详见this thread)
所以我们需要以其他方式做到这一点。
就我而言,我决定使用课程(PARAM
)
的声明:强>
class PARAM {
public static class Abstract {
protected void injectExtras(Intent intent){
// do nothing for action don't need to extas...
}
}
public static class FOO extends Abstract { // this is for ACTION.FOO
public static final String P1_KEY="p1";
public static final String P2_KEY="p2";
String p1;
int p2;
public FOO(String p1, int p2){
this.p1 =p1;
this.p2 =p2;
}
@Override
protected void injectExtras(Intent intent){
intent.putExtra(P1_KEY,this.p1);
intent.putExtra(P2_KEY,this.p2);
}
}
public static class BAR extends Abstract{ // this is for ACTION.BAR
...
}
}
使用示例:
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
ACTION anEnum = ACTION.getEnum(action);
switch (anEnum) {
case FOO:
Bundle extras = intent.getExtras();
String p1 = extras.getString(PARAM.FOO.P1_KEY);
int p2 = extras.getString(PARAM.FOO.P2_KEY);
// do something with p1 & p2;
break;
}
}
<强>最后,强>
我使用'ACTION &
PARAM`作为服务的内部类,BroadcastReceiver或者其他
例如:
public class MyIntentService extends IntentService {
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
ACTION anEnum = ACTION.getEnum(action);
switch (anEnum) {
case INVALID: // it can be occured by old version's legacy alarm.
Log.w("INVALID action occured:"+action);
break;
case FOO:
// do something for FOO
break;
case BAR:
// do something for FOO
break;
defalut:
Log.d("Unimplement! action:"+action);
break;
}
}
}
public static enum ACTION {...}
public static class PARAM {...}
}
答案 1 :(得分:1)
所有Intent.ACTION_ *字段都是字符串常量。
在JDK 7 android使用JDK 6或5进行编译之前,不能使用带字符串的开关。所以你不能在Android上使用该方法
但您可以使用else if
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF) {
// Do
} else if (intent.getAction().equals(Intent.ANYTINGS) {
//do
}
答案 2 :(得分:0)
3个月前,我回答了这个问题。现在我有了比以前更好的想法。
简单地说,您不必在onReceive方法中使用switch语句。 因为有比它更有效的方式。 使用反射使每个意图助手自己处理!
请参阅以下代码:
public class SOReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {INTENT.onHandleIntent(this, intent);}
public static class INTENT {
public static void onHandleIntent(SOReceiver intentService, Intent intent) {
for (Class<?> clazz : INTENT.class.getDeclaredClasses()) {
// note: this code use getSimpleName!
if (clazz.getSimpleName().equals(intent.getAction())) {
try {
IntentInterface instance = (IntentInterface) clazz.newInstance();
instance.onReceive(intentService, intent);
} catch (Exception e) {
e.printStackTrace();
}
return;
}
}
// unexpected INTENT arrived.
}
private static interface IntentInterface {
void onReceive(SOReceiver intentService, Intent intent);
}
public static class EACH_ACTION implements IntentInterface {
// usage ex: SOReceiver.INTENT.EACH_ACTION.start(context,3.0,1);
private static final String PARAM_FOO = "PARAM_FOO";
private static final String PARAM_BAR = "PARAM_BAR";
public static void start(Context context, double foo, int bar) {
Intent intent = new Intent();
intent.setAction(EACH_ACTION.class.getSimpleName()); // necessary
intent.setClass(context, SOReceiver.class); // optional, but recommended.
intent.putExtra(PARAM_FOO,foo);
intent.putExtra(PARAM_BAR,bar);
context.sendBroadcast(intent);
// or if you want to use this as pending intent.
// PendingIntent.getBroadcast(context,0,intent,0);
}
@Override
public void onReceive(SOReceiver intentService, Intent intent) {
Bundle extras = intent.getExtras();
double foo = extras.getDouble(PARAM_FOO);
int bar = extras.getInt(PARAM_BAR);
// ... do what ever you want to do with this intent and parameters ...
}
}
}
}
这比旧答案更好。它简短易读,易于添加更多意图。