私は今、2週間かけて解決しようとしているちょっとした問題を抱えています。できる限り詳しくお伝えするように心がけますが、不明な点がありましたらお尋ねください。Bluetoothチャットアプリケーションに取り組んでいます。クラッシュの原因となる 4 行のコードを除いて、すべて正常に動作します。接続をクリックすると送信される二次アクティビティを作成しました。
これはレイアウトです (connection_activity.xml):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView android:id="@+id/title_paired_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title_paired_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/paired_devices"
android:textIsSelectable="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="1"
/>
<TextView android:id="@+id/title_new_devices"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/title_other_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/new_devices"
android:textIsSelectable="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="2"
/>
<Button android:id="@+id/button4"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/button_scan"
/>
</LinearLayout>
これは、ペアリングされた使用可能なデバイスを表示するための 2 つのリストを使用した単純なアクティビティです (いずれかのデバイスに接続するためにクリックできます)。
次に、ソース コード (ConnectionActivity.java) があります。
/* In this activity I will manage the secondary layout (for bluetooth connection)*/
package com.andrecl.interapption;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
public class ConnectionActivity extends Activity implements OnClickListener {
/* Initializing part */
BluetoothAdapter mBluetoothAdapter;
BluetoothSocket mSocket;
BluetoothDevice mDevice;
public static String EXTRA_DEVICE_ADDRESS = "device_address"; // this is the
// number
// code of
// the
// devices
Button scanButton; //the scan button
StartDiscover startDiscover; //start discover thread
/* For intent request */
private static final int REQUEST_ENABLE_BT = 1;
/* Arrays for storing the lists of paired devices and found devices */
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
/* Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.connection_activity);
// Get the local Bluetooth adapter (as in the other activity)
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
/* Make sure bt is on! */
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
/* Initialize array adapters. One for already paired devices and one for newly discovered devices */
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.connection_activity);
mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.connection_activity);
/* Find and set up the ListView for paired devices */
ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(mDeviceClickListener); //later implemented if you click on a device
/* Find and set up the ListView for newly discovered devices */
ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(mDeviceClickListener); //later implemented if you click on a device
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
/*Finally we start listening if the scanbutton is pressed*/
startDiscover = new StartDiscover();
scanButton = (Button) findViewById(R.id.button4);
scanButton.setOnClickListener(this);
/* List of paired devices */ //removed the array printing due to crash
if (pairedDevices.size() > 0) {
findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
Toast.makeText(this, "Paired devices", Toast.LENGTH_SHORT).show();
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
} else {
Toast.makeText(this, "No paired devices", Toast.LENGTH_SHORT).show();
String noDevices = getResources().getText(R.string.none_paired).toString();
mPairedDevicesArrayAdapter.add(noDevices);
}
}
/* The scan button */
public void onClick(View v) {
startDiscover.start();
v.setVisibility(View.GONE); // so you can't use the button again (avoid Button spamming). GONE: This view is invisible, and it doesn't take any space for layout purposes
}
/*The Discover thread*/
private class StartDiscover extends Thread{
private Handler dHandler = new Handler();
public void run(){
dHandler.post(new Runnable(){
public void run(){
mBluetoothAdapter.startDiscovery();
toast();
}
});
}
}
public void toast(){
Toast.makeText(this, "Scanning - Please wait", Toast.LENGTH_SHORT).show();
}
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already DEACTIVATED DUE TO CRASH
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setTitle(R.string.select_device); //Due to space issues, the instructions are displayed in the title.
/*If no devices found ... removed due to crashing*/
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
@Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
// The on-click listener for all devices in the ListViews
private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
// Cancel discovery because it's costly and we're about to connect
mBluetoothAdapter.cancelDiscovery();
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// Create the result Intent and include the MAC address
Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
// Set result and finish this Activity
setResult(Activity.RESULT_OK, intent);
finish();
}
};
}
アプリ全体がクラッシュする原因は次の とおりです (これらの行を削除してもクラッシュしません)。 および mPairedDevicesArrayAdapter.add(noDevices);
以降 mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); および mNewDevicesArrayAdapter.add(noDevices);
これらの 4 行が問題のようです。誰かが私が間違っていたことを特定できますか?
御時間ありがとうございます、
編集:申し訳ありませんが、LogCat は次のとおりです。
05-22 19:25:27.592: D/libEGL(27711): loaded /vendor/lib/egl/libEGL_POWERVR_SGX540_120.so
05-22 19:25:27.600: D/libEGL(27711): loaded /vendor/lib/egl/libGLESv1_CM_POWERVR_SGX540_120.so
05-22 19:25:27.600: D/libEGL(27711): loaded /vendor/lib/egl/libGLESv2_POWERVR_SGX540_120.so
05-22 19:25:27.787: D/OpenGLRenderer(27711): Enabling debug mode 0
05-22 19:25:30.928: D/OpenGLRenderer(27711): Flushing caches (mode 0)
05-22 19:25:44.225: E/ArrayAdapter(27711): You must supply a resource ID for a TextView
05-22 19:25:44.225: D/AndroidRuntime(27711): Shutting down VM
05-22 19:25:44.225: W/dalvikvm(27711): threadid=1: thread exiting with uncaught exception (group=0x40bfc1f8)
05-22 19:25:44.233: E/AndroidRuntime(27711): FATAL EXCEPTION: main
05-22 19:25:44.233: E/AndroidRuntime(27711): java.lang.IllegalStateException: ArrayAdapter requires the resource ID to be a TextView
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:386)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.AbsListView.obtainView(AbsListView.java:2210)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.ListView.measureHeightOfChildren(ListView.java:1244)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.ListView.onMeasure(ListView.java:1155)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.View.measure(View.java:12775)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1385)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.LinearLayout.measureVertical(LinearLayout.java:670)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.View.measure(View.java:12775)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.View.measure(View.java:12775)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.LinearLayout.measureVertical(LinearLayout.java:822)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.LinearLayout.onMeasure(LinearLayout.java:563)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.View.measure(View.java:12775)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4709)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.FrameLayout.onMeasure(FrameLayout.java:293)
05-22 19:25:44.233: E/AndroidRuntime(27711): at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2240)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.View.measure(View.java:12775)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1117)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2505)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.os.Looper.loop(Looper.java:137)
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.app.ActivityThread.main(ActivityThread.java:4514)
05-22 19:25:44.233: E/AndroidRuntime(27711): at java.lang.reflect.Method.invokeNative(Native Method)
05-22 19:25:44.233: E/AndroidRuntime(27711): at java.lang.reflect.Method.invoke(Method.java:511)
05-22 19:25:44.233: E/AndroidRuntime(27711): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
05-22 19:25:44.233: E/AndroidRuntime(27711): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
05-22 19:25:44.233: E/AndroidRuntime(27711): at dalvik.system.NativeStart.main(Native Method)
05-22 19:25:44.233: E/AndroidRuntime(27711): Caused by: java.lang.ClassCastException: android.widget.LinearLayout cannot be cast to android.widget.TextView
05-22 19:25:44.233: E/AndroidRuntime(27711): at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:379)
05-22 19:25:44.233: E/AndroidRuntime(27711): ... 30 more
05-22 19:26:44.717: I/Process(27711): Sending signal. PID: 27711 SIG: 9