Android:如何使用从广播收到的意图的switch-case

时间:2013-12-18 14:20:08

标签: android android-intent broadcastreceiver android-broadcast

我想分析从广播接收的意图。因为不同的广播可能有不同的意图。为了评估不同的广播,我想使用这样的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

3 个答案:

答案 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
}

Official documentation

答案 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 ...
            }
        }
    }
}

这比旧答案更好。它简短易读,易于添加更多意图。