- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我写了两个应用程序(目标 Gingerbread )。比方说 app1 和 app2。 App1 有两个以“BOOT_COMPLETED”开始的服务,它们以返回值 START_STICKY 开始。它们在不同的线程中运行。使长话短说。其中一项服务正在监视串行端口上的传入数据(一种应用程序与串行端口另一端接口(interface)通信的代理)。另一个有一个监听器来监视一些系统状态并等待来自其他应用程序的一些“指令”。我知道它们运行良好,因为它们列在正在运行的服务中,并且我添加了一些代码,当某些特定数据来自串行端口时,它们会强制它们执行某些操作。
现在的问题是:我写了 app2。它尝试绑定(bind)到 app1 中的一项服务。我用了android-developper文档并在 app1 和 app2 中的服务之间实现了双向通信。因为我只有少量非常简单的数据要发送,所以我按照建议使用了一个信使。我基本上只使用“什么,arg1 和 arg2”我没有使用文档建议的 AIDL 接口(interface)。
这是在 app1 中声明服务的 androidmanifest 部分,我也尝试绑定(bind)。
<service android:name=".ModemWatcherService"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- Service name -->
<action android:name="com.admetric.modemwatcher.Service" />
</intent-filter>
</service>
那么,下面是app1中处理这个问题的几种方法:
@Override
public IBinder onBind(Intent intent) {
Log.d(TAG, "entering onBind");
return mMessenger.getBinder();
}
/**
* Handler of incoming messages from clients.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
String logMessage = "Received meaasge what= %d, arg1= %d, arg2= %d" + String.valueOf(msg.what) + String.valueOf(msg.arg1) + String.valueOf( msg.arg2);
Log.d(TAG, logMessage);
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case .....
more code here for the application
default:
super.handleMessage(msg);
}
}
}
@Override
public void onCreate() {
mHandler = new Handler();
startSignalLevelListener();
Log.i(TAG, "Just did onCreated");
// Display a notification about us starting. We put an icon in the status bar.
// showNotification();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
对于app2,这里是建立双向通信绑定(bind)的相关代码:
public final class ComWithIoMcu extends Service {
private static final String TAG = "ComWithIoMcu";
/** Messenger for communicating with service. */
static Messenger mServiceMcu = null;
/** Flag indicating whether we have called bind on the service. */
boolean mIsBound;
/**
* Command to the service to register a client, receiving callbacks
* from the service. The Message's replyTo field must be a Messenger of
* the client where callbacks should be sent.
*/
static final int MSG_REGISTER_CLIENT = 1;
/**
* Command to the service to unregister a client, ot stop receiving callbacks
* from the service. The Message's replyTo field must be a Messenger of
* the client as previously given with MSG_REGISTER_CLIENT.
*/
static final int MSG_UNREGISTER_CLIENT = 2;
/**
* Command to forward a string command to the I/O MCU
*/
public static final int MSG_SEND_STRING_TO_IOMCU = 3;
/** List of supported commands
*
*/
...... more code ....
/**
* Handler of incoming messages from service.
*/
class IncomingHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_UNSOL_MESSAGE:
Log.d(TAG, "Received from service: " + msg.arg1);
break;
default:
super.handleMessage(msg);
}
}
}
/**
* Target we publish for clients to send messages to IncomingHandler.
*/
final Messenger mMessenger = new Messenger(new IncomingHandler());
boolean mBound;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mServiceMcu = new Messenger(service);
Log.d(TAG, "Attached.");
// We want to monitor the service for as long as we are
// connected to it.
try {
Message msg = Message.obtain(null,
MSG_REGISTER_CLIENT);
msg.replyTo = mMessenger;
mServiceMcu.send(msg);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
Log.e(TAG, "ModemWatcherService is not running");
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mServiceMcu = null;
mBound = false;
}
};
void doBindService() {
// Establish a connection with the service. We use an explicit
// class name because there is no reason to be able to let other
// applications replace our component.
//bindService(new Intent(this, MessengerService.class), mConnection, Context.BIND_AUTO_CREATE);
try {
Intent intentForMcuService = new Intent();
Log.d(TAG, "Before init intent.componentName");
intentForMcuService.setComponent(new ComponentName("com.admetric.modemwatcher", "ModemWatcherService"));
Log.d(TAG, "Before bindService");
if (bindService(intentForMcuService, mConnection, 0)){
Log.d(TAG, "Binding to Modem Watcher returned true");
} else {
Log.d(TAG, "Binding to Modem Watcher returned false");
}
} catch (SecurityException e) {
Log.e(TAG, "can't bind to ModemWatcherService, check permission in Manifest");
}
mIsBound = true;
Log.d(TAG, "Binding.");
}
void doUnbindService() {
if (mIsBound) {
// If we have received the service, and hence registered with
// it, then now is the time to unregister.
if (mServiceMcu != null) {
try {
Message msg = Message.obtain(null, MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mServiceMcu.send(msg);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
Log.d(TAG, "Unbinding.");
}
}
查看正在运行的服务,我可以看到我在 app2 中创建的服务正在运行。 Logcat 显示我尝试绑定(bind) ModemWatcherService 但未找到。这是 logcat 的有趣部分
12-05 17:22:59.884 D/ComWithIoMcu( 547): Before init intent.componentName
12-05 17:22:59.884 D/ComWithIoMcu( 547): Before bindService
12-05 17:22:59.888 D/ComWithIoMcu( 547): Binding to Modem Watcher returned false
12-05 17:22:59.888 D/ComWithIoMcu( 547): Binding.
12-05 17:22:59.888 W/ActivityManager( 89): Unable to start service Intent { cmp=com.admetric.modemwatcher/ModemWatcherService }: not found
我的第一个想法是我缺少权限,但 bindService() 可以抛出安全异常,在这种情况下并非如此,我检查了一下,它返回 false,原因不明。另外,我知道在 app1 中,永远不会调用 onBind 来证明绑定(bind)从未发生过。所以 logcat 消息“未找到”是有道理的,但我在其 list 中声明该服务是公开的。这可能是一个简单的错误,但我已经关注这个问题一段时间了,但我没有找到原因。知道为什么 app2 在 app1 中找不到服务吗?我只使用剪切和粘贴名称,这样我就不会在名称中犯下愚蠢的错误输入错误。我是否缺少某种权限?我需要做一些额外的步骤来为整个系统发布服务吗?这是我第一次尝试从另一个应用程序访问一个应用程序中的内容,所以我可能错过了一些东西。
最佳答案
您的 ComponentName
构造不正确。传入类名时必须像这样完全限定:
intentForMcuService.setComponent(new ComponentName("com.admetric.modemwatcher",
"com.admetric.modemwatcher.ModemWatcherService"));
另一件事,如果您在应用程序边界之外引用 Service
,最好不要使用 ComponentName
来引用它,即使它确实可以正常工作.一种更常见的方法是为您的 Intent
创建自定义 ACTION 字符串,并让 Service
过滤该操作。
关于android - 从另一个应用程序绑定(bind)到服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13745779/
我正在通过 labrepl 工作,我看到了一些遵循此模式的代码: ;; Pattern (apply #(apply f %&) coll) ;; Concrete example user=> (a
我从未向应用商店提交过应用,但我会在不久的将来提交。 到目前为止,我对为 iPhone 而非 iPad 进行设计感到很自在。 我了解,通过将通用PAID 应用放到应用商店,客户只需支付一次就可以同时使
我有一个应用程序,它使用不同的 Facebook 应用程序(2 个不同的 AppID)在 Facebook 上发布并显示它是“通过 iPhone”/“通过 iPad”。 当 Facebook 应用程序
我有一个要求,我们必须通过将网站源文件保存在本地 iOS 应用程序中来在 iOS 应用程序 Webview 中运行网站。 Angular 需要服务器来运行应用程序,但由于我们将文件保存在本地,我们无法
所以我有一个单页客户端应用程序。 正常流程: 应用程序 -> OAuth2 服务器 -> 应用程序 我们有自己的 OAuth2 服务器,因此人们可以登录应用程序并获取与用户实体关联的 access_t
假设我有一个安装在用户设备上的 Android 应用程序 A,我的应用程序有一个 AppWidget,我们可以让其他 Android 开发人员在其中以每次安装成本为基础发布他们的应用程序推广广告。因此
Secrets of the JavaScript Ninja中有一个例子它提供了以下代码来绕过 JavaScript 的 Math.min() 函数,该函数需要一个可变长度列表。 Example:
当我分别将数组和对象传递给 function.apply() 时,我得到 NaN 的 o/p,但是当我传递对象和数组时,我得到一个数字。为什么会发生这种情况? 由于数组也被视为对象,为什么我无法使用它
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界. 这篇CFSDN的博客文章ASP转换格林威治时间函数DateDiff()应用由作者收集整理,如果你
我正在将列表传递给 map并且想要返回一个带有合并名称的 data.frame 对象。 例如: library(tidyverse) library(broom) mtcars %>% spl
我有一个非常基本的问题,但我不知道如何实现它:我有一个返回数据框,其中每个工具的返回值是按行排列的: tmp<-as.data.frame(t(data.frame(a=rnorm(250,0,1)
我正在使用我的 FB 应用创建群组并邀请用户加入我的应用群组,第一次一切正常。当我尝试创建另一个组时,出现以下错误: {"(OAuthException - #4009) (#4009) 在有更多用户
我们正在开发一款类似于“会说话的本”应用程序的 child 应用程序。它包含大量用于交互式动画的 JPEG 图像序列。 问题是动画在 iPad Air 上播放正常,但在 iPad 2 上播放缓慢或滞后
我关注 clojure 一段时间了,它的一些功能非常令人兴奋(持久数据结构、函数式方法、不可变状态)。然而,由于我仍在学习,我想了解如何在实际场景中应用,证明其好处,然后演化并应用于更复杂的问题。即,
我开发了一个仅使用挪威语的应用程序。该应用程序不使用本地化,因为它应该仅以一种语言(挪威语)显示。但是,我已在 Info.plist 文件中将“本地化 native 开发区域”设置为“no”。我还使用
读完 Anthony's response 后上a style-related parser question ,我试图说服自己编写单体解析器仍然可以相当紧凑。 所以而不是 reference ::
multicore 库中是否有类似 sapply 的东西?还是我必须 unlist(mclapply(..)) 才能实现这一点? 如果它不存在:推理是什么? 提前致谢,如果这是一个愚蠢的问题,我们深表
我喜欢在窗口中弹出结果,以便更容易查看和查找(例如,它们不会随着控制台继续滚动而丢失)。一种方法是使用 sink() 和 file.show()。例如: y <- rnorm(100); x <- r
我有一个如下所示的 spring mvc Controller @RequestMapping(value="/new", method=RequestMethod.POST) public Stri
我正在阅读 StructureMap关于依赖注入(inject),首先有两部分初始化映射,具体类类型的接口(interface),另一部分只是实例化(请求实例)。 第一部分需要配置和设置,这是在 Bo
我是一名优秀的程序员,十分优秀!