【Android】service call intent 分析

service.cpp里有对intent的处理

188                        } else if (strcmp(argv[optind], "intent") == 0) {
189
190                        	char* action = NULL;
191                        	char* dataArg = NULL;
192                        	char* type = NULL;
193                        	int launchFlags = 0;
194                        	char* component = NULL;
195                        	int categoryCount = 0;
196                        	char* categories[16];
197
198                        	char* context1 = NULL;
199
200                            optind++;
201
202                        	while (optind < argc)
203                        	{
204                        		char* key = strtok_r(argv[optind], "=", &context1);
205                        		char* value = strtok_r(NULL, "=", &context1);
206
207                                // we have reached the end of the XXX=XXX args.
208                                if (key == NULL) break;
209
210                        		if (strcmp(key, "action") == 0)
211                        		{
212                        			action = value;
213                        		}
214                        		else if (strcmp(key, "data") == 0)
215                        		{
216                        			dataArg = value;
217                        		}
218                        		else if (strcmp(key, "type") == 0)
219                        		{
220                        			type = value;
221                        		}
222                        		else if (strcmp(key, "launchFlags") == 0)
223                        		{
224                        			launchFlags = atoi(value);
225                        		}
226                        		else if (strcmp(key, "component") == 0)
227                        		{
228                        			component = value;
229                        		}
230                        		else if (strcmp(key, "categories") == 0)
231                        		{
232                        			char* context2 = NULL;
233                        			int categoryCount = 0;
234                        			categories[categoryCount] = strtok_r(value, ",", &context2);
235
236                        			while (categories[categoryCount] != NULL)
237                        			{
238                        				categoryCount++;
239                        				categories[categoryCount] = strtok_r(NULL, ",", &context2);
240                        			}
241                        		}
242
243                                optind++;
244                        	}
245
246                            writeString16(data, action);
247                            writeString16(data, dataArg);
248                            writeString16(data, type);
249                       		data.writeInt32(launchFlags);
250                            writeString16(data, component);
251
252                            if (categoryCount > 0)
253                            {
254                                data.writeInt32(categoryCount);
255                                for (int i = 0 ; i < categoryCount ; i++)
256                                {
257                                    writeString16(data, categories[i]);
258                                }
259                            }
260                            else
261                            {
262                                data.writeInt32(0);
263                            }
264
265                            // for now just set the extra field to be null.
266                       		data.writeInt32(-1);
267                        } else {
268                            aerr << "service: unknown option " << argv[optind] << endl;
269                            wantsUsage = true;
270                            result = 10;
271                            break;
272                        }

我们尝试进行调用,
准备使用service call 使用如下调用功能
       Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);           
        mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);             
        getPackageManager().queryIntentActivities(mainIntent, 0);


 $ service call package 42 intent action=android.intent.action.MAIN cat
egories=android.intent.category.LAUNCHER i32 0 i32 0
             
Result: Parcel(
  0x00000000: fffffffd 00000019 006e0055 006e006b '........U.n.k.n.'
  0x00000010: 0077006f 0020006e 00520055 00200049 'o.w.n. .U.R.I. .'
  0x00000020: 00790074 00650070 0020003a 00340037 't.y.p.e.:. .7.4.'
  0x00000030: 00310037 00300032 00000034          '7.1.2.0.4...    ')

出错了

log
01-09 02:52:17.500 1075-1980/? W/System.err: java.lang.IllegalArgumentException: Unknown URI type: 7471204
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.net.Uri$1.createFromParcel(Uri.java:1779)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.net.Uri$1.createFromParcel(Uri.java:1769)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.content.Intent.readFromParcel(Intent.java:8680)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.content.Intent.<init>(Intent.java:8675)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.content.Intent$1.createFromParcel(Intent.java:8666)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.content.Intent$1.createFromParcel(Intent.java:8665)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:662)
01-09 02:52:17.501 1075-1980/? W/System.err:     at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3732)
01-09 02:52:17.501 1075-1980/? W/System.err:     at android.os.Binder.execTransact(Binder.java:577)

查看

Intent.java

    public static final Parcelable.Creator<Intent> CREATOR
            = new Parcelable.Creator<Intent>() {
        public Intent createFromParcel(Parcel in) {
            return new Intent(in);
        }
        public Intent[] newArray(int size) {
            return new Intent[size];
        }
    };

    /** @hide */
    protected Intent(Parcel in) {
        readFromParcel(in);
    }

    public void readFromParcel(Parcel in) {
        setAction(in.readString());
        mData = Uri.CREATOR.createFromParcel(in);
        mType = in.readString();
        mFlags = in.readInt();
        mPackage = in.readString();
        mComponent = ComponentName.readFromParcel(in);

        if (in.readInt() != 0) {
            mSourceBounds = Rect.CREATOR.createFromParcel(in);
        }

        int N = in.readInt();
        if (N > 0) {
            mCategories = new ArraySet<String>();
            int i;
            for (i=0; i<N; i++) {
                mCategories.add(in.readString().intern());
            }
        } else {
            mCategories = null;
        }

        if (in.readInt() != 0) {
            mSelector = new Intent(in);
        }

        if (in.readInt() != 0) {
            mClipData = new ClipData(in);
        }
        mContentUserHint = in.readInt();
        mExtras = in.readBundle();
    }

Uri.java
   public static final Parcelable.Creator<Uri> CREATOR
            = new Parcelable.Creator<Uri>() {
        public Uri createFromParcel(Parcel in) {
            int type = in.readInt();
            switch (type) {
                case NULL_TYPE_ID: return null;
                case StringUri.TYPE_ID: return StringUri.readFrom(in);
                case OpaqueUri.TYPE_ID: return OpaqueUri.readFrom(in);
                case HierarchicalUri.TYPE_ID:
                    return HierarchicalUri.readFrom(in);
            }

            throw new IllegalArgumentException("Unknown URI type: " + type);
        }

        public Uri[] newArray(int size) {
            return new Uri[size];
        }
    };


service.cpp里写parcel数据没有按照intent标准去写导致的问题,
我们按照intent的格式去写数据就可以。但是这样的调用还是显得比较繁琐,没有直接在应用层调用方便。

           附,IPackageManager.java里的处理 @Override public android.content.pm.ParceledListSlice queryIntentActivities(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId) throws android.os.RemoteException
            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                android.content.pm.ParceledListSlice _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    if ((intent!=null)) {
                        _data.writeInt(1);
                        intent.writeToParcel(_data, 0);
                    }
                    else {
                        _data.writeInt(0);
                    }
                    _data.writeString(resolvedType);
                    _data.writeInt(flags);
                    _data.writeInt(userId);
                    mRemote.transact(Stub.TRANSACTION_queryIntentActivities, _data, _reply, 0);
                    _reply.readException();
                    if ((0!=_reply.readInt())) {
                        _result = android.content.pm.ParceledListSlice.CREATOR.createFromParcel(_reply);
                    }
                    else {
                        _result = null;
                    }
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

    static final int TRANSACTION_queryIntentActivities = (android.os.IBinder.FIRST_CALL_TRANSACTION + 41);


                case TRANSACTION_queryIntentActivities:
                {
                    data.enforceInterface(DESCRIPTOR);
                    android.content.Intent _arg0;
                    if ((0!=data.readInt())) {
                        _arg0 = android.content.Intent.CREATOR.createFromParcel(data);
                    }
                    else {
                        _arg0 = null;
                    }
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    int _arg2;
                    _arg2 = data.readInt();
                    int _arg3;
                    _arg3 = data.readInt();
                    android.content.pm.ParceledListSlice _result = this.queryIntentActivities(_arg0, _arg1, _arg2, _arg3);
                    reply.writeNoException();
                    if ((_result!=null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    }
                    else {
                        reply.writeInt(0);
                    }
                    return true;
                }

获取intent数据出错
                    _arg0 = android.content.Intent.CREATOR.createFromParcel(data);


@Override public android.content.pm.ParceledListSlice queryIntentActivities(android.content.Intent intent, java.lang.String resolvedType, int flags, int userId) throws android.os.RemoteException

            {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                android.content.pm.ParceledListSlice _result;
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    if ((intent!=null)) {
                        _data.writeInt(1);
                        intent.writeToParcel(_data, 0);
                    }
                    else {
                        _data.writeInt(0);
                    }
                    _data.writeString(resolvedType);
                    _data.writeInt(flags);
                    _data.writeInt(userId);
                    mRemote.transact(Stub.TRANSACTION_queryIntentActivities, _data, _reply, 0);
                    _reply.readException();
                    if ((0!=_reply.readInt())) {
                        _result = android.content.pm.ParceledListSlice.CREATOR.createFromParcel(_reply);
                    }
                    else {
                        _result = null;
                    }
                }
                finally {
                    _reply.recycle();
                    _data.recycle();
                }
                return _result;
            }

    static final int TRANSACTION_queryIntentActivities = (android.os.IBinder.FIRST_CALL_TRANSACTION + 41);


                case TRANSACTION_queryIntentActivities:
                {
                    data.enforceInterface(DESCRIPTOR);
                    android.content.Intent _arg0;
                    if ((0!=data.readInt())) {
                        _arg0 = android.content.Intent.CREATOR.createFromParcel(data);
                    }
                    else {
                        _arg0 = null;
                    }
                    java.lang.String _arg1;
                    _arg1 = data.readString();
                    int _arg2;
                    _arg2 = data.readInt();
                    int _arg3;
                    _arg3 = data.readInt();
                    android.content.pm.ParceledListSlice _result = this.queryIntentActivities(_arg0, _arg1, _arg2, _arg3);
                    reply.writeNoException();
                    if ((_result!=null)) {
                        reply.writeInt(1);
                        _result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
                    }
                    else {
                        reply.writeInt(0);
                    }
                    return true;
                }

获取intent数据出错
                    _arg0 = android.content.Intent.CREATOR.createFromParcel(data);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值