Android的Native方式广播intent


原文:https://blog.csdn.net/alien75/article/details/50789168 
版权声明:本文为博主原创文章,转载请附上博文链接!

 

本文是在“在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 service
const 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.java
typedef enum URI_TYPE_ID
{
    NULL_TYPE_ID    = 0,
    StringUri       = 1,
    OpaqueUri       = 2,
    HierarchicalUri = 3,
};
 
// Parcel.java
typedef 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.java
const 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 type
        data.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 failure
            ALOGE("sendBroadcast(%s) caught exception %d\n", String8(action_str).string(), exceptionCode);
        }
    }
}
 
// Intent.java
const 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);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值