Android2.1 BroadCastReceiver接收不到数据,啥原因

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android2.1 BroadCastReceiver接收不到数据,啥原因相关的知识,希望对你有一定的参考价值。

android2.1 BroadCastReceiver接收不到数据的原因是因为不支持某些文件类型。具体解决方式为:
1.蓝牙默认支持所有图片,所有视频,所有音频,文本类型,html,zip,excel,word,ppt,pdf等类型。
2.使用RE文件夹,找到package/app/bluetooth,对其目录下的AndroidManifest.xml文件的<data android:mimeType="" />,添加相应的类型即可。
3.具体的添加内容为<receiver android:name=".GetData">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
这一段写到application标记里面。
参考技术A 把<receiver android:name=".GetData">
<intent-filter>

<action android:name="android.provider.Telephony.SMS_RECEIVED" />

</intent-filter>
</receiver>
这一段写到application标记里面。本回答被提问者和网友采纳
参考技术B   广播接收者的注册分为静态注册和动态注册,在AndroidManifest.xml中配置的属于静态注册,而动态注册需要调用context中的registerReceiver方法进行注册。

  这次我们对动态注册进行分析

  1、代码如下:

  ?1

  2IntentFilter counterActionFilter = new
IntentFilter(CounterService.BROADCAST_COUNTER_ACTION);

  registerReceiver(counterActionReceiver, counterActionFilter);

  注释:

  (1)、IntentFilter
顾名思义,IntentFilter对象负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理。
IntentFilter实行“白名单”管理,即只列出组件乐意接受的Intent,但IntentFilter只会过滤隐式Intent,显式的Intent会直接传送到目标组件。
Android组件可以有一个或多个IntentFilter,每个IntentFilter之间相互独立,只需要其中一个验证通过则可。

  创建IntentFilter对象的源码:

  public class IntentFilter implements Parcelable

  private int mPriority;

  private final ArrayList mActions;

  public IntentFilter(String action)

  mPriority = 0;

  mActions = new ArrayList();

  addAction(action);

  

  。。。

  

  把CounterService.BROADCAST_COUNTER_ACTION字符串放到了mActions中。

  2、registerReceiver的源码:

  14public class ContextWrapper extends Context

  Context mBase;

  public ContextWrapper(Context base)

  mBase = base;

  

  @Override

  public Intent registerReceiver(

  BroadcastReceiver receiver, IntentFilter filter)

  return mBase.registerReceiver(receiver, filter);

  

  。。。

  

  mBase是ContextImpl对象。

  3、mBase.registerReceiver(receiver, filter)的源码:

  class ContextImpl extends Context

  。。。。

  @Override

  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter
filter)

  return registerReceiver(receiver, filter, null, null);

  

  @Override

  public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter
filter,

  String broadcastPermission, Handler scheduler)

  return registerReceiverInternal(receiver, filter, broadcastPermission,

  scheduler, getOuterContext());

  

  private Intent registerReceiverInternal(BroadcastReceiver receiver,

  IntentFilter filter, String broadcastPermission,

  Handler scheduler, Context context)

  IIntentReceiver rd = null;

  if (receiver != null)

  if (mPackageInfo != null && context != null)

  if (scheduler == null)

  scheduler = mMainThread.getHandler();

  

  rd = mPackageInfo.getReceiverDispatcher(

  receiver, context, scheduler,

  mMainThread.getInstrumentation(), true);

   else

  if (scheduler == null)

  scheduler = mMainThread.getHandler();

  

  rd = new LoadedApk.ReceiverDispatcher(

  receiver, context, scheduler, null, true).getIIntentReceiver();

  

  

  try

  return ActivityManagerNative.getDefault().registerReceiver(

  mMainThread.getApplicationThread(),

  rd, filter, broadcastPermission);

   catch (RemoteException e)

  return null;

  

  

  。。。

  

  注释:

  (1)通过getReceiverDispatcher()将广播接收者封装成实现IintentReceiver接口的binder本地对象rd。

  3.1 mPackageInfo.getReceiverDispatcher()的源码:

  public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,

  Context context, Handler handler,

  Instrumentation instrumentation, boolean registered)

  synchronized (mReceivers)

  LoadedApk.ReceiverDispatcher rd = null;

  HashMap map = null;

  if (registered)

  map = mReceivers.get(context);

  if (map != null)

  rd = map.get(r);

  

  

  if (rd == null)

  rd = new ReceiverDispatcher(r, context, handler,

  instrumentation, registered);

  if (registered)

  if (map == null)

  map = new HashMap();

  mReceivers.put(context, map);

  

  map.put(r, rd);

  

   else

  rd.validate(context, handler);

  

  return rd.getIIntentReceiver();

  

  

  3.2 new ReceiverDispatcher 的源码:

  final static class InnerReceiver extends IIntentReceiver.Stub

  final WeakReference mDispatcher;

  final LoadedApk.ReceiverDispatcher mStrongRef;

  InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong)

  mDispatcher = new WeakReference(rd);

  mStrongRef = strong ? rd : null;

  

  

  final IIntentReceiver.Stub mIIntentReceiver;

  final BroadcastReceiver mReceiver;

  final Context mContext;

  final Handler mActivityThread;

  final Instrumentation mInstrumentation;

  final boolean mRegistered;

  ReceiverDispatcher(BroadcastReceiver receiver, Context context,

  Handler activityThread, Instrumentation instrumentation,

  boolean registered)

  if (activityThread == null)

  throw new NullPointerException("Handler must not be null");

  

  mIIntentReceiver = new InnerReceiver(this, !registered);

  mReceiver = receiver;

  mContext = context;

  mActivityThread = activityThread;

  mInstrumentation = instrumentation;

  mRegistered = registered;

  mLocation = new IntentReceiverLeaked(null);

  mLocation.fillInStackTrace();

  

  IIntentReceiver getIIntentReceiver()

  return mIIntentReceiver;

  

  mReceiver表示广播接受者

  mContext表示activity组件,也就是这个广播接受者在哪一个activity中注册的。

  mActivityThread表示与activity相关的handle

  mIIntentReceiver指向了创建的ReceiverDispatcher对象。

  (2)ActivityManagerNative. getDefault()获得是ActivityManagerProxy对象

  总结:activity组件在注册一个广播接收者时,并不是真的将广播接收者注册到ActivityManagerService中,而是将与它相关联的IntentReceiver对象注册到ActivityManagerService中,当ActivityManagerService接受到一个广播的时候,他就会根据广播的类型在内部找到对应的IntentReceiver对象,然后再通过他找到广播接收者。

  4、ActivityManagerProxy中怎么实现的registerReceiver方法 ,源码:

  22public Intent registerReceiver(IApplicationThread caller,

  IIntentReceiver receiver,

  IntentFilter filter, String perm) throws RemoteException

  

  Parcel data = Parcel.obtain();

  Parcel reply = Parcel.obtain();

  data.writeInterfaceToken(IActivityManager.descriptor);

  data.writeStrongBinder(caller != null ? caller.asBinder() : null);

  data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);

  filter.writeToParcel(data, 0);

  data.writeString(perm);

  mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);

  reply.readException();

  Intent intent = null;

  int haveIntent = reply.readInt();

  if (haveIntent != 0)

  intent = Intent.CREATOR.createFromParcel(reply);

  

  reply.recycle();

  data.recycle();

  return intent;

  

  注释:binder代理对象mRemote向ActivityManagerService发送一个类型为REGISTER_RECEIVER_TRANSACTION的进程间通信请求。

  5、ActivityManagerService中的源码:

  92public final class ActivityManagerService extends
ActivityManagerNative

  implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

  public Intent registerReceiver(IApplicationThread caller,

  IIntentReceiver receiver, IntentFilter filter, String permission)

  synchronized(this)

  ProcessRecord callerApp = null;

  if (caller != null)

  callerApp = getRecordForAppLocked(caller);

  if (callerApp == null)

  throw new SecurityException(

  "Unable to find app for caller " + caller

  + " (pid=" + Binder.getCallingPid()

  + ") when registering receiver " + receiver);

  

  

  List allSticky = null;

  // Look for any matching sticky broadcasts...

  Iterator actions = filter.actionsIterator();

  if (actions != null)

  while (actions.hasNext())

  String action = (String)actions.next();

  allSticky = getStickiesLocked(action, filter, allSticky);

  

   else

  allSticky = getStickiesLocked(null, filter, allSticky);

  

  // The first sticky in the list is returned directly back to

  // the client.

  Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;

  if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter

  + ": " + sticky);

  if (receiver == null)

  return sticky;

  

  ReceiverList rl

  = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());

  if (rl == null)

  rl = new ReceiverList(this, callerApp,

  Binder.getCallingPid(),

  Binder.getCallingUid(), receiver);

  if (rl.app != null)

  rl.app.receivers.add(rl);

   else

  try

  receiver.asBinder().linkToDeath(rl, 0);

   catch (RemoteException e)

  return sticky;

  

  rl.linkedToDeath = true;

  

  mRegisteredReceivers.put(receiver.asBinder(), rl);

  

  BroadcastFilter bf = new BroadcastFilter(filter, rl, permission);

  rl.add(bf);

  if (!bf.debugCheck())

  Slog.w(TAG, "==> For Dynamic broadast");

  

  mReceiverResolver.addFilter(bf);

  // Enqueue broadcasts for all existing stickies that match

  // this filter.

  if (allSticky != null)

  ArrayList receivers = new ArrayList();

  receivers.add(bf);

  int N = allSticky.size();

  for (int i=0; i

  Intent intent = (Intent)allSticky.get(i);

  BroadcastRecord r = new BroadcastRecord(intent, null,

  null, -1, -1, null, receivers, null, 0, null, null,

  false, true, true);

  if (mParallelBroadcasts.size() == 0)

  scheduleBroadcastsLocked();

  

  mParallelBroadcasts.add(r);

  

  

  return sticky;

  

  

  。。。

  
参考技术C 一般是权限和配置的问题 参考技术D 你的广播注册了吗?

Android 教程

01 Android概述 02 Android环境设置 03 Android架构 04 Android应用程序组件 05 Android Hello World示例 06 Android资源组织和访问
07 Android Activities 08 Android服务 09 Android广播接收器 10 Android内容提供商 11 Android碎片 12 Android意图和过滤器
13 Android UI布局 14 Android UI控件 15 Android事件处理 16 Android样式和主题 17 Android自定义组件 18 Android拖放
19 Android通知 20 Android基于位置的服务 21 Android发送电子邮件 22 Android发送短信 23 Android手机通话 24 发布Android应用程序
25 Android警报对话框 26 Android动画 27 Android音频捕获 28 Android音频管理器 29 Android自动完成 30 Android最佳实践
31 Android蓝牙 32 Android相机 33 Android剪贴板 34 Android自定义字体 35 Android数据备份 36 Android开发者工具
37 Android模拟器 38 Android Facebook集成 39 Android手势 40 Android谷歌地图 41 Android图片效果 42 Android图像切换器
43 Android内部存储 44 Android JetPlayer 45 Android JSON Parser 46 Android Linkedin集成 47 Android Loading Spinner 48 Android本地化
49 Android登录屏幕 50 Android MediaPlayer 51 Android多点触控 52 Android导航 53 Android网络连接 54 Android NFC指南
55 Android PHP_MYSQL 56 Android进度条 57 Android进度条使用 58 Android推送通知 59 Android RenderScript 60 Android RSS阅读器
61 Android Screen Cast 62 Android SDK Manager 63 Android传感器 64 Android会话管理 65 Android共享偏好设置 66 Android SIP协议
67 Android拼写检查器 68 Android SQLite数据库 69 Android支持库 70 Android测试 71 Android文字转语音 72 Android TextureView
73 Android Twitter集成 74 Android UI设计 75 Android UI Patterns 76 Android UI测试 77 Android WebView 78 Android Wi-Fi
79 Android小部件 80 Android XML Parser

以上是关于Android2.1 BroadCastReceiver接收不到数据,啥原因的主要内容,如果未能解决你的问题,请参考以下文章

如何移植android2.1源代码到自己的手机上

ubuntu tar命令

怎样在android2.1上看CCTV news频道?

android2.1移植到S3C6410后,SD卡功能使用不正常。

阅读《Android 从入门到精通》(31)——Intent

阅读《Android 从入门到精通》(31)——Intent