├── README.md ├── Android.mk ├── NativeBroadCast.cpp ├── NativeBroadCastHandler.h └── NativeBroadCastHandler.cpp /README.md: -------------------------------------------------------------------------------- 1 | # AndroidNativeSendBroadcast 2 | Android在native代码中发送广播 3 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_SRC_FILES:= NativeBroadCast.cpp NativeBroadCastHandler.cpp \ 6 | 7 | LOCAL_SHARED_LIBRARIES:= libutils libutils libbinder liblog 8 | 9 | LOCAL_C_INCLUDES := $(TOP)/frameworks/base/include/ \ 10 | $(LOCAL_PATH)/ \ 11 | 12 | 13 | LOCAL_MODULE:= nativeBroadcast 14 | 15 | LOCAL_PRELINK_MODULE:= false 16 | 17 | include $(BUILD_EXECUTABLE) 18 | 19 | include $(call all-makefiles-under,$(LOCAL_PATH)) 20 | -------------------------------------------------------------------------------- /NativeBroadCast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "NativeBroadCastHandler.h" 6 | using namespace android; 7 | 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | sp proc(ProcessState::self()); 12 | ProcessState::self()->startThreadPool(); 13 | IPCThreadState::self()->joinThreadPool(); 14 | 15 | const char ACTION_POWER_DOWN_NOW[] = "cn.native.broadcasst.test end"; 16 | sendBroadcast(ACTION_POWER_DOWN_NOW, NULL); 17 | return 0; 18 | } 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /NativeBroadCastHandler.h: -------------------------------------------------------------------------------- 1 | #ifndef NATIVECRASHHANDLER_NATIVEBROADCASTHANDLER_H 2 | #define NATIVECRASHHANDLER_NATIVEBROADCASTHANDLER_H 3 | #include 4 | #include 5 | #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MCA", __VA_ARGS__) 6 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "MCA", __VA_ARGS__) 7 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "MCA", __VA_ARGS__) 8 | 9 | #ifdef __cplusplus 10 | extern "C" { 11 | #endif 12 | namespace android{ 13 | void sendBroadcast(const char* action_str, const char* uri_str); 14 | } 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif 19 | 20 | #endif //NATIVECRASHHANDLER_NATIVEBROADCASTHANDLER_H 21 | -------------------------------------------------------------------------------- /NativeBroadCastHandler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "NativeBroadCastHandler.h" 11 | 12 | namespace android 13 | { 14 | 15 | namespace { 16 | sp gActivityManagerService; 17 | const int kActivityManagerServicePollDelay = 500000; // 0.5s 18 | const char* kActivityManagerServiceName = "activity"; 19 | 20 | Mutex gLock; 21 | 22 | class DeathNotifier : public IBinder::DeathRecipient 23 | { 24 | public: 25 | DeathNotifier() { 26 | } 27 | 28 | virtual void binderDied(const wp& who) { 29 | ALOGV("binderDied"); 30 | Mutex::Autolock _l(gLock); 31 | gActivityManagerService.clear(); 32 | ALOGW("ActivityManager service died!"); 33 | } 34 | }; 35 | 36 | sp gDeathNotifier; 37 | }; 38 | 39 | 40 | const sp& getActivityManagerService() 41 | { 42 | Mutex::Autolock _l(gLock); 43 | if (gActivityManagerService.get() == 0) { 44 | sp sm = defaultServiceManager(); 45 | sp binder; 46 | do { 47 | binder = sm->getService(String16(kActivityManagerServiceName)); 48 | if (binder != 0) { 49 | break; 50 | } 51 | ALOGW("ActivityManagerService not published, waiting..."); 52 | usleep(kActivityManagerServicePollDelay); 53 | } while(true); 54 | if (gDeathNotifier == NULL) { 55 | gDeathNotifier = new DeathNotifier(); 56 | } 57 | binder->linkToDeath(gDeathNotifier); 58 | gActivityManagerService = binder; 59 | } 60 | ALOGE_IF(gActivityManagerService == 0, "no ActivityManagerService!?"); 61 | return gActivityManagerService; 62 | } 63 | 64 | 65 | typedef enum URI_TYPE_ID 66 | { 67 | NULL_TYPE_ID = 0, 68 | StringUri = 1, 69 | OpaqueUri = 2, 70 | HierarchicalUri = 3, 71 | }; 72 | 73 | 74 | typedef enum VALUE_TYPE 75 | { 76 | VAL_NULL = -1, 77 | VAL_STRING = 0, 78 | VAL_INTEGER = 1, 79 | VAL_MAP = 2, 80 | VAL_BUNDLE = 3, 81 | VAL_PARCELABLE = 4, 82 | VAL_SHORT = 5, 83 | VAL_LONG = 6, 84 | VAL_FLOAT = 7, 85 | VAL_DOUBLE = 8, 86 | VAL_BOOLEAN = 9, 87 | VAL_CHARSEQUENCE = 10, 88 | VAL_LIST = 11, 89 | VAL_SPARSEARRAY = 12, 90 | VAL_BYTEARRAY = 13, 91 | VAL_STRINGARRAY = 14, 92 | VAL_IBINDER = 15, 93 | VAL_PARCELABLEARRAY = 16, 94 | VAL_OBJECTARRAY = 17, 95 | VAL_INTARRAY = 18, 96 | VAL_LONGARRAY = 19, 97 | VAL_BYTE = 20, 98 | VAL_SERIALIZABLE = 21, 99 | VAL_SPARSEBOOLEANARRAY = 22, 100 | VAL_BOOLEANARRAY = 23, 101 | VAL_CHARSEQUENCEARRAY = 24, 102 | }; 103 | 104 | 105 | const uint32_t BROADCAST_INTENT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 13; 106 | 107 | void sendBroadcast(const char* action_str, const char* uri_str) 108 | { 109 | Parcel data, reply; 110 | 111 | sp am = getActivityManagerService(); 112 | if(am == NULL) 113 | { 114 | ALOGE("sendBroadcast(%s) get ActivityManager failed\n", String8(uri_str).string()); 115 | return; 116 | } 117 | 118 | data.writeInterfaceToken(String16("android.app.IActivityManager")); 119 | data.writeStrongBinder(NULL); /* caller */ 120 | /* intent */ 121 | data.writeString16(String16(action_str)); /* action */ 122 | if(uri_str == NULL) 123 | { 124 | data.writeInt32(NULL_TYPE_ID); 125 | } 126 | else 127 | { 128 | // only support StringUri type 129 | data.writeInt32(StringUri); /* Uri - type */ 130 | data.writeString16(String16(uri_str)); /* uri string if URI_TYPE_ID set */ 131 | } 132 | data.writeString16(NULL, 0); /* type */ 133 | data.writeInt32(0); /* flags */ 134 | data.writeString16(NULL, 0); /* package name */ 135 | data.writeString16(NULL, 0); /* ComponentName */ 136 | data.writeInt32(0); /* source bound - size */ 137 | data.writeInt32(0); /* Categories - size */ 138 | data.writeInt32(0); /* selector - size */ 139 | data.writeInt32(0); /* ClipData */ 140 | data.writeInt32(-1); /* bundle(extras) size */ 141 | if(1) 142 | { 143 | data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L' 144 | int oldPos = data.dataPosition(); 145 | { /* writeMapInternal */ 146 | data.writeInt32(1); /* size */ 147 | data.writeInt32(VAL_STRING); 148 | data.writeString16(String16("status")); 149 | data.writeInt32(VAL_STRING); 150 | data.writeString16(String16("OFF")); 151 | } 152 | int newPos = data.dataPosition(); 153 | data.setDataPosition(oldPos - 8); 154 | data.writeInt32(newPos - oldPos); /* length */ 155 | data.setDataPosition(newPos); 156 | } 157 | /* end of intent */ 158 | data.writeString16(NULL, 0); /* resolvedType */ 159 | data.writeStrongBinder(NULL); /* resultTo */ 160 | data.writeInt32(-1); /* result code */ 161 | data.writeString16(NULL, 0); /* result data */ 162 | data.writeInt32(-1); /* no result extra */ 163 | data.writeString16(NULL, 0); /* permission */ 164 | data.writeInt32(false); /* app operation in AppOpsManager */ 165 | data.writeInt32(false); /* serialized */ 166 | data.writeInt32(false); /* sticky */ 167 | data.writeInt32(false); /* userid */ 168 | LOGI("am->transact"); 169 | status_t ret = am->transact(BROADCAST_INTENT_TRANSACTION, data, &reply); 170 | if (ret == NO_ERROR) 171 | { 172 | int32_t exceptionCode = reply.readExceptionCode(); 173 | if (!exceptionCode) 174 | { 175 | ALOGD("sendBroadcast(%s) succeed\n", String8(action_str).string()); 176 | } 177 | else 178 | { 179 | // An exception was thrown back; fall through to return failure 180 | ALOGE("sendBroadcast(%s) caught exception %d\n", String8(action_str).string(), exceptionCode); 181 | } 182 | } 183 | } 184 | } --------------------------------------------------------------------------------