无法从我的 DialogFragment 中的 MainActivity 访问 ArrayList<String>
Trouble accessing an ArrayList<String> from MainActivity in my DialogFragment
我需要能够从我的 MainActivity.java class.
中的 ArrayList (ScannedDevicesArrayList) 传递我的 ScannedDevicesListItemDialog.java class 索引
我尝试在 MainActivity.java class 中创建函数 (getScannedDevicesArrayList) 以返回 ArrayList,然后在对话框的 onClick 中调用该函数。然而,当 运行 程序运行时,只要我点击对话框中的一个项目,应用程序就会崩溃。
如何在我的对话框中引用 MainActivity.java 中的这个 ArrayList 以便能够用它做一些简单的事情,例如在单击对话框中的项目时将它的索引打印到控制台?
MainActivity.java
package com.august.customtisensortagclient;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
BluetoothManager mBluetoothManager;
BluetoothAdapter mBluetoothAdapter;
BluetoothLeScanner mBluetoothScanner;
TextView console;
Button clear_button;
public ArrayList<String> scannedDevicesArrayList = new ArrayList<String>();
int scannedDevicesArrayListTop = -1;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
ArrayAdapter<String> myArrayAdapter;
ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
console = (TextView) findViewById(R.id.Console);
console.append("Console is working...\n");
registerClearButton();
// Functional code
setupBluetooth();
startScanning();
registerScannedDevicesListCallback();
// Test code
}
public void clearConsole(){
console.setText("Console is working...\n");
scannedDevicesArrayList.clear();
myArrayAdapter.notifyDataSetChanged();
scannedDevicesArrayListTop = -1;
}
private void registerScannedDevicesListCallback() {
list = (ListView) findViewById(R.id.myListView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view;
DialogFragment newFragment = new ScannedDevicesListItemDialog();
newFragment.show(getSupportFragmentManager(), "ScannedDevicesListItemDialog");
}
});
}
private void registerClearButton(){
clear_button = (Button) findViewById(R.id.clear_button);
clear_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
clearConsole();
}
});
}
public void addDeviceToScannedDevicesList() {
list = (ListView) findViewById(R.id.myListView);
myArrayAdapter = new ArrayAdapter<String>(this,
R.layout.my_list_view_items, scannedDevicesArrayList);
list.setAdapter(myArrayAdapter);
}
public void setupBluetooth() {
// Get BluetoothAdapter
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Get BluetoothLeScanner
mBluetoothScanner = mBluetoothAdapter.getBluetoothLeScanner();
// Make sure Bluetooth is enabled
if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// Make sure location is enabled
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
while (!scannedDevicesArrayList.contains(result.getDevice().getAddress()) && (result.getRssi() > -55)){
scannedDevicesArrayList.add(result.getDevice().getAddress());
scannedDevicesArrayListTop++;
addDeviceToScannedDevicesList();
console.append(Integer.toString(result.getRssi()));
}
}
};
public ArrayList<String> getScannedDevicesArrayList(){
return scannedDevicesArrayList;
}
public int getScannedDevicesArrayListTop() {
return scannedDevicesArrayListTop;
}
public void startScanning() {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
mBluetoothScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
mBluetoothScanner.stopScan(leScanCallback);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, " +
"this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
}
ScannedDevicesListItemDialog.java
package com.august.customtisensortagclient;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
public class ScannedDevicesListItemDialog extends DialogFragment {
String[] options = {"Left", "Right"};
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Connect as Left or Right?")
.setItems(options, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity mainActivity = new MainActivity();
ArrayList<String> thisScannedDevicesArrayList = mainActivity.getScannedDevicesArrayList();
((MainActivity)getActivity()).console.setText("Worked");
((MainActivity)getActivity()).console.setText(thisScannedDevicesArrayList.get(0));
}
});
return builder.create();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="0dp">
<TextView
android:id="@+id/Console"
android:layout_width="272dp"
android:layout_height="46dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="200dp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:scaleType="fitCenter"
app:srcCompat="@mipmap/gruneisen_logo" />
<Button
android:id="@+id/clear_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/Console"
android:layout_marginBottom="131dp"
android:text="CLEAR" />
<ListView
android:id="@+id/myListView"
android:layout_width="match_parent"
android:layout_height="379dp" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
my_list_view_items.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="44sp">
</TextView>
MainActivity mainActivity = new MainActivity();
不是您访问Activity的方式。这也不是您访问已创建的 class 的方式,但那是另一个问题。
使用该代码,您正在创建 MainActivity 的新实例,而不是获取当前存在的实例。这意味着您的 ArrayList 为空,因为它从未被初始化。
要访问您的列表,请使用 getActivity()
函数,该函数将获取 Fragment 的父实例 Activity,并将其转换为 MainActivity:
MainActivity mainActivity = (MainActivity) getActivity();
我需要能够从我的 MainActivity.java class.
中的 ArrayList (ScannedDevicesArrayList) 传递我的 ScannedDevicesListItemDialog.java class 索引我尝试在 MainActivity.java class 中创建函数 (getScannedDevicesArrayList) 以返回 ArrayList,然后在对话框的 onClick 中调用该函数。然而,当 运行 程序运行时,只要我点击对话框中的一个项目,应用程序就会崩溃。
如何在我的对话框中引用 MainActivity.java 中的这个 ArrayList 以便能够用它做一些简单的事情,例如在单击对话框中的项目时将它的索引打印到控制台?
MainActivity.java
package com.august.customtisensortagclient;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.method.ScrollingMovementMethod;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
BluetoothManager mBluetoothManager;
BluetoothAdapter mBluetoothAdapter;
BluetoothLeScanner mBluetoothScanner;
TextView console;
Button clear_button;
public ArrayList<String> scannedDevicesArrayList = new ArrayList<String>();
int scannedDevicesArrayListTop = -1;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
ArrayAdapter<String> myArrayAdapter;
ListView list;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
console = (TextView) findViewById(R.id.Console);
console.append("Console is working...\n");
registerClearButton();
// Functional code
setupBluetooth();
startScanning();
registerScannedDevicesListCallback();
// Test code
}
public void clearConsole(){
console.setText("Console is working...\n");
scannedDevicesArrayList.clear();
myArrayAdapter.notifyDataSetChanged();
scannedDevicesArrayListTop = -1;
}
private void registerScannedDevicesListCallback() {
list = (ListView) findViewById(R.id.myListView);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view;
DialogFragment newFragment = new ScannedDevicesListItemDialog();
newFragment.show(getSupportFragmentManager(), "ScannedDevicesListItemDialog");
}
});
}
private void registerClearButton(){
clear_button = (Button) findViewById(R.id.clear_button);
clear_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
clearConsole();
}
});
}
public void addDeviceToScannedDevicesList() {
list = (ListView) findViewById(R.id.myListView);
myArrayAdapter = new ArrayAdapter<String>(this,
R.layout.my_list_view_items, scannedDevicesArrayList);
list.setAdapter(myArrayAdapter);
}
public void setupBluetooth() {
// Get BluetoothAdapter
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Get BluetoothLeScanner
mBluetoothScanner = mBluetoothAdapter.getBluetoothLeScanner();
// Make sure Bluetooth is enabled
if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
}
// Make sure location is enabled
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
// Device scan callback.
private ScanCallback leScanCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
while (!scannedDevicesArrayList.contains(result.getDevice().getAddress()) && (result.getRssi() > -55)){
scannedDevicesArrayList.add(result.getDevice().getAddress());
scannedDevicesArrayListTop++;
addDeviceToScannedDevicesList();
console.append(Integer.toString(result.getRssi()));
}
}
};
public ArrayList<String> getScannedDevicesArrayList(){
return scannedDevicesArrayList;
}
public int getScannedDevicesArrayListTop() {
return scannedDevicesArrayListTop;
}
public void startScanning() {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
mBluetoothScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
AsyncTask.execute(new Runnable() {
@Override
public void run() {
mBluetoothScanner.stopScan(leScanCallback);
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, " +
"this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
}
ScannedDevicesListItemDialog.java
package com.august.customtisensortagclient;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
public class ScannedDevicesListItemDialog extends DialogFragment {
String[] options = {"Left", "Right"};
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Connect as Left or Right?")
.setItems(options, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MainActivity mainActivity = new MainActivity();
ArrayList<String> thisScannedDevicesArrayList = mainActivity.getScannedDevicesArrayList();
((MainActivity)getActivity()).console.setText("Worked");
((MainActivity)getActivity()).console.setText(thisScannedDevicesArrayList.get(0));
}
});
return builder.create();
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dp"
tools:layout_editor_absoluteX="16dp"
tools:layout_editor_absoluteY="0dp">
<TextView
android:id="@+id/Console"
android:layout_width="272dp"
android:layout_height="46dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="200dp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="70dp"
android:layout_alignParentBottom="true"
android:scaleType="fitCenter"
app:srcCompat="@mipmap/gruneisen_logo" />
<Button
android:id="@+id/clear_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignStart="@+id/Console"
android:layout_marginBottom="131dp"
android:text="CLEAR" />
<ListView
android:id="@+id/myListView"
android:layout_width="match_parent"
android:layout_height="379dp" />
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
my_list_view_items.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="44sp">
</TextView>
MainActivity mainActivity = new MainActivity();
不是您访问Activity的方式。这也不是您访问已创建的 class 的方式,但那是另一个问题。
使用该代码,您正在创建 MainActivity 的新实例,而不是获取当前存在的实例。这意味着您的 ArrayList 为空,因为它从未被初始化。
要访问您的列表,请使用 getActivity()
函数,该函数将获取 Fragment 的父实例 Activity,并将其转换为 MainActivity:
MainActivity mainActivity = (MainActivity) getActivity();