本文是在“在Android中使用native程序(非Java)来广播intent”这篇博文的基础上的完整实现,实现了在Native下广播一个即将关机的通知。

#define LOG_TAG "IntentTest"#include <fcntl.h>#include <unistd.h>#include <binder/MemoryHeapBase.h>#include <binder/ProcessState.h>#include <binder/IPCThreadState.h>#include <binder/IServiceManager.h>#include <binder/IInterface.h>#include <binder/Parcel.h>namespace android {namespace {    sp<IBinder>              gActivityManagerService;    const int                kActivityManagerServicePollDelay = 500000;      // 0.5s    const char*              kActivityManagerServiceName      = "activity";  // default name    Mutex                    gLock;    class DeathNotifier : public IBinder::DeathRecipient    {    public:        DeathNotifier() {        }        virtual void binderDied(const wp<IBinder>& who) {            ALOGV("binderDied");            Mutex::Autolock _l(gLock);            gActivityManagerService.clear();            ALOGW("ActivityManager service died!");        }    };    sp<DeathNotifier>         gDeathNotifier;}; // namespace anonymous// establish binder interface to ActivityManager serviceconst sp<IBinder>& getActivityManagerService(){Mutex::Autolock _l(gLock);if (gActivityManagerService.get() == 0) {sp<IServiceManager> sm = defaultServiceManager();sp<IBinder> binder;do {binder = sm->getService(String16(kActivityManagerServiceName));if (binder != 0) {break;}ALOGW("ActivityManagerService not published, waiting...");usleep(kActivityManagerServicePollDelay);} while(true);        if (gDeathNotifier == NULL) {            gDeathNotifier = new DeathNotifier();        }        binder->linkToDeath(gDeathNotifier);gActivityManagerService = binder;}ALOGE_IF(gActivityManagerService == 0, "no ActivityManagerService!?");return gActivityManagerService;}// Uri.javatypedef enum URI_TYPE_ID{NULL_TYPE_ID    = 0,StringUri       = 1,OpaqueUri       = 2,HierarchicalUri = 3,};// Parcel.javatypedef enum VALUE_TYPE{VAL_NULL = -1,VAL_STRING = 0,VAL_INTEGER = 1,VAL_MAP = 2,VAL_BUNDLE = 3,VAL_PARCELABLE = 4,VAL_SHORT = 5,VAL_LONG = 6,VAL_FLOAT = 7,VAL_DOUBLE = 8,VAL_BOOLEAN = 9,VAL_CHARSEQUENCE = 10,VAL_LIST  = 11,VAL_SPARSEARRAY = 12,VAL_BYTEARRAY = 13,VAL_STRINGARRAY = 14,VAL_IBINDER = 15,VAL_PARCELABLEARRAY = 16,VAL_OBJECTARRAY = 17,VAL_INTARRAY = 18,VAL_LONGARRAY = 19,VAL_BYTE = 20,VAL_SERIALIZABLE = 21,VAL_SPARSEBOOLEANARRAY = 22,VAL_BOOLEANARRAY = 23,VAL_CHARSEQUENCEARRAY = 24,};// IActivityManager.javaconst uint32_t BROADCAST_INTENT_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION + 13;void sendBroadcast(const char* action_str, const char* uri_str){Parcel data, reply;sp<IBinder> am = getActivityManagerService();if(am == NULL){ALOGE("sendBroadcast(%s) get ActivityManager failed\n", String8(uri_str).string());return;}data.writeInterfaceToken(String16("android.app.IActivityManager"));  data.writeStrongBinder(NULL);             /* caller *//* intent */data.writeString16(String16(action_str)); /* action */if(uri_str == NULL){data.writeInt32(NULL_TYPE_ID);}else{// only support StringUri typedata.writeInt32(StringUri);             /* Uri - type */data.writeString16(String16(uri_str));  /* uri string if URI_TYPE_ID set */}data.writeString16(NULL, 0);              /* type */data.writeInt32(0);                       /* flags */data.writeString16(NULL, 0);              /* package name */data.writeString16(NULL, 0);              /* ComponentName */data.writeInt32(0);                       /* source bound - size */data.writeInt32(0);                       /* Categories - size */data.writeInt32(0);                       /* selector - size */data.writeInt32(0);                       /* ClipData */data.writeInt32(-1);                      /* bundle(extras) size */if(1){data.writeInt32(0x4C444E42); // 'B' 'N' 'D' 'L'int oldPos = data.dataPosition();{ /* writeMapInternal */data.writeInt32(1); /* size */data.writeInt32(VAL_STRING);data.writeString16(String16("status"));data.writeInt32(VAL_STRING);data.writeString16(String16("OFF"));}int newPos = data.dataPosition();data.setDataPosition(oldPos - 8);data.writeInt32(newPos - oldPos); /* length */data.setDataPosition(newPos);}/* end of intent */data.writeString16(NULL, 0);  /* resolvedType */data.writeStrongBinder(NULL); /* resultTo */data.writeInt32(-1);          /* result code */data.writeString16(NULL, 0);  /* result data */data.writeInt32(-1);          /* no result extra */data.writeString16(NULL, 0);  /* permission */data.writeInt32(false);       /* app operation in AppOpsManager */data.writeInt32(false);       /* serialized */data.writeInt32(false);       /* sticky */data.writeInt32(false);       /* userid */status_t ret = am->transact(BROADCAST_INTENT_TRANSACTION, data, &reply);if (ret == NO_ERROR){int32_t exceptionCode = reply.readExceptionCode();if (!exceptionCode){ALOGD("sendBroadcast(%s) succeed\n", String8(action_str).string());} else{// An exception was thrown back; fall through to return failureALOGE("sendBroadcast(%s) caught exception %d\n", String8(action_str).string(), exceptionCode);}}}// Intent.javaconst char ACTION_POWER_DOWN_NOW[] = "android.intent.action.POWER_DOWN_NOW";};using namespace android;int main(int argc, char **argv){android::ProcessState::self()->startThreadPool();int i;status_t status;printf("IntentTest start\n");sendBroadcast(ACTION_POWER_DOWN_NOW, NULL);printf("IntentTest stop\n");  return 0;}

对应的java代码形如:

Intent intent = new Intent(ACTION_POWER_DOWN_NOW);intent.putExtra("status", "OFF");mContext.sendBroadcast(intent);



更多相关文章

  1. Android(安卓)8.1静态广播的使用以及添加权限
  2. android 8.0 ,9.0 静态广播不显示问题处理
  3. android广播的使用
  4. Android拨号键盘增加魔力爱心数字
  5. [置顶] ANDROID 返回,菜单和HOME键的监听
  6. Android使用自定义view在指定时间内匀速画一条直线的实例代码
  7. Android(安卓)BroadcastRecevicer广播分类
  8. android关于AndroidManifest.xml详细分析
  9. android中检测网络是否断开

随机推荐

  1. Android Device Monitor工具的使用
  2. Android调试技术
  3. Android Non-UI to UI Thread Communicat
  4. 【Android】 Android中对于时间的转换
  5. Android(安卓)Material Design之Snackbar
  6. android 开发实用
  7. 输入法问题
  8. 生成Google Map KeyGen
  9. Android之MediaCodec使用经验分享
  10. Android7 增加双以太网eth1的支持