我是Android / Glass开发的新手,但我已经开始解决看起来非常具有挑战性的任务了。我试图通过蓝牙向Glass和我的计算机发送String消息。
我有蓝牙功能的服务,我有一个嵌套在该服务中的活页夹类。但是,当我尝试调用某个绑定程序的方法时,应用程序崩溃了。
崩溃发生在这一行:
mBluetoothService.requestConnect();
导致此错误:
java.lang.NoClassDefFoundError: com.riverlab.glassbluetooth.BluetoothService $ RemoteConnectionBinder
运行此代码:
MainActivity.java:处理菜单项
package com.riverlab.glassbluetooth;
import com.example.glassbluetooth.R;
import com.keyboardr.glassremote.client.RemoteMessenger;
import com.keyboardr.glassremote.client.RemoteMessengerService;
import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends Activity {
private boolean mResumed;
private GlassBluetoothService.MainBinder mService;
private BluetoothService.RemoteConnectionBinder mBluetoothService;
//Name is deceptive, this binder is for the voice control
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder binderService) {
if(binderService instanceof GlassBluetoothService.MainBinder) {
mService = (GlassBluetoothService.MainBinder) binderService;
openOptionsMenu();
}
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
}
};
//Connection for the bluetooth binder
private ServiceConnection mBluetoothConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName arg0, IBinder binderService) {
if(binderService instanceof RemoteMessengerService.RemoteConnectionBinder){
mBluetoothService = (BluetoothService.RemoteConnectionBinder) binderService;
openOptionsMenu();
}
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
// TODO Auto-generated method stub
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(mService == null) {
bindService(new Intent(this, GlassBluetoothService.class), mConnection, 0);
}
if (mBluetoothService == null)
{
bindService(new Intent(this, BluetoothService.class), mBluetoothConnection, 0);
}
}
@Override
protected void onResume() {
super.onResume();
mResumed = true;
}
@Override
protected void onPause() {
super.onPause();
mResumed = false;
}
@Override
public void openOptionsMenu() {
if (mResumed && mService != null) {
super.openOptionsMenu();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
@Override
public void onDestroy() {
super.onDestroy();
finish();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.read_connection_status:
mService.speakConnectionStatus();
finish();
return true;
case R.id.connect:
mBluetoothService.requestConnect();
finish();
return true;
case R.id.stop:
stopService(new Intent(this, GlassBluetoothService.class));
stopService(new Intent(this, BluetoothService.class));
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onOptionsMenuClosed(Menu menu) {
super.onOptionsMenuClosed(menu);
unbindService(mConnection);
}
}
BluetoothService.java:处理蓝牙
package com.riverlab.glassbluetooth;
import java.util.UUID;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.speech.tts.TextToSpeech;
import com.example.glassbluetooth.R;
import com.keyboardr.glassremote.client.RemoteMessenger;
import com.keyboardr.glassremote.client.RemoteMessengerImpl;
import com.keyboardr.glassremote.client.StringRemoteMessengerService;
import com.keyboardr.glassremote.client.RemoteMessenger.Callback;
import com.keyboardr.glassremote.client.RemoteMessengerService.RemoteConnectionBinder;
import com.keyboardr.glassremote.common.receiver.MessageReceiver;
import com.keyboardr.glassremote.common.receiver.StringMessageReader;
import com.keyboardr.glassremote.common.sender.MessageSender;
import com.keyboardr.glassremote.common.sender.StringMessageSender;
public class BluetoothService extends Service
{
private final RemoteConnectionBinder mBinder = new RemoteConnectionBinder();
private RemoteMessenger<String, String> mMessenger;
public class RemoteConnectionBinder extends Binder implements
RemoteMessenger<String, String> {
@Override
public void setCallback(Callback<? super String> callback) {
mMessenger.setCallback(callback);
}
@Override
public boolean isConnected() {
return mMessenger.isConnected();
}
@Override
public void requestConnect() {
mMessenger.requestConnect();
}
@Override
public void disconnect() {
mMessenger.disconnect();
}
@Override
public void sendMessage(String arg0) throws IllegalStateException {
// TODO Auto-generated method stub
}
}
public void onCreate()
{
super.onCreate();
mMessenger = new RemoteMessengerImpl<String, String>(UUID.randomUUID(), new StringMessageSender(), new StringMessageReader());
}
public void onStartCommand()
{
mMessenger.requestConnect();
while (!mMessenger.isConnected());
mMessenger.sendMessage("Connection Succesful");
}
@Override
public void onDestroy() {
mMessenger.disconnect();
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
mMessenger.setCallback(null);
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
mMessenger.setCallback(null);
mMessenger.disconnect();
return super.onUnbind(intent);
}
}
两个文件都在同一个包中。我在我的buildpath中添加了三个jar文件,它们似乎与问题无关,但是如果这可能会导致问题,请告诉我。我在Ubuntu 12.04上使用Eclipse ADT Build:v22.3.0-887826
提前感谢您的帮助!我无法想出这个。
编辑:这是RemoteMessenger
package com.keyboardr.glassremote.client;
import java.lang.ref.WeakReference;
import java.util.UUID;
import android.bluetooth.BluetoothDevice;
import com.keyboardr.glassremote.common.receiver.MessageReceiver;
import com.keyboardr.glassremote.common.receiver.StringMessageReader;
import com.keyboardr.glassremote.common.sender.MessageSender;
import com.keyboardr.glassremote.common.sender.StringMessageSender;
/**
* Interface for communicating with the remote server. There should be a
* <code>MessageService<R, S></code> running on that remote server.
*
* @author Joshua Brown
*
* @param <S>
* the type of messages this <code>RemoteMessenger</code> will send
* to the remote server. The corresponding
* <code>MessageService</code> on the remote server should receive
* messages as <code>S</code> or some superclass thereof.
* @param <R>
* the type of messages this <code>RemoteMessenger</code> will
* receive from the remote server. The corresponding
* <code>MessageService</code> on the remote server should send
* messages as <code>R</code> or some subclass thereof.
*/
public interface RemoteMessenger<S, R> {
/**
* Callback interface for <code>RemoteMessenger</code>. All callbacks will
* be called on the main thread.
*
* @param <M>
* message type to receive
*/
public static interface Callback<M> {
/**
* The <code>RemoteMessenger</code> has connected to
* <code>remoteDevice</code> and is able to send and receive messages
*
* @param remoteDevice
* the <code>BluetoothDevice</code> this
* <code>RemoteMessenger</code> has connected to
*/
public void onConnected(BluetoothDevice remoteDevice);
/**
* The <code>RemoteMessenger</code> has failed to connect to any
* devices. Messages cannot be sent or received
*/
public void onConnectionFailed();
/**
* The <code>RemoteMessenger</code> has disconnected from
* <code>remoteDevice</code> and can no longer send or receive messages
*
* @param remoteDevice
* the <code>BluetoothDevice</code> this
* <code>RemoteMessenger</code> was connected to
*/
public void onDisconnected(BluetoothDevice remoteDevice);
/**
* The <code>RemoteMessenger</code> has received a message from the
* remote server
*
* @param message
* the <code>M</code> message received from the remote server
*/
public void onReceiveMessage(M message);
}
/**
* Sets callback destination. Implementations should use
* {@link WeakReference WeakReferences} to ensure the
* <code>RemoteMessenger</code> does not inadvertently keep the
* <code>Callback</code> from being GCed
*
* @param callback
*/
public void setCallback(Callback<? super R> callback);
/**
* Checks if this <code>RemoteMessenger</code> is connected to a remote
* server
*
* @return <code>true</code> iff this <code>RemoteMessenger</code> can send
* and receive messages from a remote server
*/
public boolean isConnected();
/**
* Attempts to connect to a remote server. Calls
* {@link Callback#onConnected(BluetoothDevice) onConnected()} callback if
* successful or {@link Callback#onConnectionFailed() onConnectionFailed()}
* if unsuccessful
*/
public void requestConnect();
/**
* Disconnects from the remote server. Calls
* {@link Callback#onDisconnected(BluetoothDevice) onDisconnected()} when
* finished
*/
public void disconnect();
/**
* Sends a <code>S</code> message to the remote server. May be called from
* the main thread
*
* @param message
* the <code>S</code> message to send
* @throws IllegalStateException
* If the <code>RemoteMessenger</code> is not connected
*/
public void sendMessage(S message) throws IllegalStateException;
public static class Factory {
private Factory() {
}
/**
* Gets an instance of <code>RemoteMessenger</code> that sends and
* receives <code>String</code> messages<br/>
* <br/>
* <b>Note:</b> Messages are separated by <code>'\n'</code> characters
*
* @param uuid
* a <code>UUID</code> shared between the remote server and
* this client. UUIDs can be obtained at <a
* href="http://www.uuidgenerator.net/">http
* ://www.uuidgenerator.net/</a> and instantiated using
* {@link UUID#fromString(String)}.
* @return a <code>RemoteMessenger</code> that sends and receives
* <code>String</code> messages
*/
public static RemoteMessenger<String, String> getStringRemoteMessenger(
UUID uuid) {
return new RemoteMessengerImpl<String, String>(uuid,
new StringMessageSender(), new StringMessageReader());
}
/**
* Get an instance of <code>RemoteMessenger</code> that sends
* <code>S</code> and receives <code>R</code> messages
*
* @param uuid
* a <code>UUID</code> shared between the remote server and
* this client. UUIDs can be obtained at <a
* href="http://www.uuidgenerator.net/">http
* ://www.uuidgenerator.net/</a> and instantiated using
* {@link UUID#fromString(String)}.
* @param sender
* the <code>MessageSender</code> providing the
* implementation for sending <code>S</code> messages
* @param receiver
* the <code>MessageReceiver</code> providing the
* implementation for receiving <code>R</code> messages
*/
public static <S, R> RemoteMessenger<S, R> getRemoteMessenger(
UUID uuid, MessageSender<S> sender, MessageReceiver<R> receiver) {
return new RemoteMessengerImpl<S, R>(uuid, sender, receiver);
}
}
}
答案 0 :(得分:1)
至于我如何添加它们,我右键单击我的项目,选择Build Path,Add External Archive,然后我选择了我的jar
这不是您如何将JAR添加到Android项目中。请撤消该操作,然后在项目中创建一个libs/
目录(如果它尚不存在),然后将JAR复制到libs/
。这不仅会自动将它们添加到编译时构建路径中,而且还会将其内容打包到APK文件中。您的方法解决了编译时构建路径,但JAR未打包在APK中,并且在运行时不可用。