Как преобразовать фрагмент в Activity Android?
У меня есть работающее приложение, использующее потоки по фрагментам, дело в том, что мне нужно изменить макет. Это больше не будет фрагментом, а стандартным действием.
Моя большая проблема в том, что я не знаю точно, где разместить то, что находится в "onViewCreated" и "onCreateView", поэтому он дает сбой, когда я вызываю "подключиться к устройству", помещенное в "onCreateView". Наверное, потому что еще рано что ли.
@Nullable
@Override
public View onCreateView(final LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState){
View view;
view = inflater.inflate(R.layout.fragment_home_2, container, false);
//Linking layout views
connectToDevice = view.findViewById(R.id.connect_to_device);
startRecording = view.findViewById(R.id.start_recording);
stopRecording = view.findViewById(R.id.stop_recording);
connectedToDevice = view.findViewById(R.id.connected_to_device);
mAdapter = new DeviceListAdapter(container.getContext(), activeDevices);
imgEkoDevice = view.findViewById(R.id.img_ekodevice);
//Enable bluetooth and start scanning thread
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
if (btAdapter != null && !btAdapter.isEnabled()) {
btAdapter.enable();
}
//Layout setup
connectedToDevice.setText(getResources().getString(R.string.welcome_to_scopefy));
//Thread setup to search for device
scanningThread = new Thread(){
@Override
public void run(){
Log.i(AppConstants.TAG, "scanning...");
LibCore.getInstance(ConnectDeviceActivity.this).startScanningForDevices(new EkoDeviceScan() {
@Override
public void foundDevice(BLEDevice bleDevice) {
//Log.i(AppPreferences.log, "foundDevice: " + bleDevice.toString());
if(activeDevices.isEmpty()){
//Adding first device to list
activeDevices.add(bleDevice);
}
else{
int i = 0;
newDevice = true;
//Checks if its already on the list
while(i < activeDevices.size() && newDevice){
if(activeDevices.get(i).getAddress().equals(bleDevice.getAddress())){
newDevice = false;
}
i++;
}
if(newDevice){
activeDevices.add(bleDevice);
}
}
//Show list and dismiss search dialog
if(connect){
showDeviceListDialog();
if(emptyListDialog != null){
emptyListDialog.dismiss();
}
connect = false;
}
}
});
}
};
LocalBroadcastManager.getInstance(ConnectDeviceActivity.this).registerReceiver(mDeviceReceiver, new IntentFilter(Parameters.DEVICE_REFRESH_DATA));
//Starting scanning background to speed up
if(LibCore.getInstance(ConnectDeviceActivity.this).getCurrentConnectedDevice() == null){
scanningThread.start();
LibCore.getInstance(ConnectDeviceActivity.this).setFiltering(true);
connected = false;
} else {
mEkoDevice = LibCore.getInstance(ConnectDeviceActivity.this).getCurrentConnectedDevice();
connected = true;
}
//Broadcast receiver for patientId
LocalBroadcastManager.getInstance(ConnectDeviceActivity.this).registerReceiver(mPatientReceiver, new IntentFilter(Parameters.PATIENT_ID));
//Listeners and receivers for device connection
LibCore.getInstance(ConnectDeviceActivity.this).setBatteryListener(new EkoDeviceBatteryLevel() {
@Override
public void deviceUpdatedBatteryLevel(float v) {
Log.i("HUEBR123", "updateou bat");
LocalBroadcastManager.getInstance(ConnectDeviceActivity.this).sendBroadcast(new Intent(Parameters.DEVICE_REFRESH_DATA).putExtra(Parameters.DEVICE_UPDATED_BATTERY_LEVEL, v));
}
});
LibCore.getInstance(ConnectDeviceActivity.this).setVolumeListener(new EkoDeviceVolume() {
@Override
public void deviceUpdatedVolumeLevel(int i) {
Log.i("HUEBR123", "updateou vol");
LocalBroadcastManager.getInstance(ConnectDeviceActivity.this).sendBroadcast(new Intent(Parameters.DEVICE_REFRESH_DATA).putExtra(Parameters.DEVICE_UPDATED_VOLUME_LEVEL, i));
}
});
//Settings
userSettingsDAO = new UserSettingsDAO(ConnectDeviceActivity.this);
settings = userSettingsDAO.getUserSettings();
//Button's listeners
connectToDevice.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
connect = true;
scanningThread.run();
showDeviceListEmptyDialog();
}
});
startRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.i(AppConstants.TAG, "starting recording...");
stopped = false;
startRecording();
//startPlayRecordThroughEko();
startRecording.setVisibility(View.GONE);
stopRecording.setVisibility(View.VISIBLE);
recording = true;
settings = userSettingsDAO.getUserSettings();
settings.getRecordingLength();
Timer timer = new Timer();
TimerTask task = new StopRecordingTask();
timer.schedule(task, settings.getRecordingLength() * 1000);
Log.i(AppConstants.TAG, "#timer starting for " + settings.getRecordingLength() + " seconds");
}
});
stopRecording.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
mEkoOutputAudioByteListener = null;
mAudioFileOutputStream.close();
writeWAVHeader(mCachedAudioRecordingFile, 4000);
//writeWAVHeader(mCachedECGRecordingFile, 500);
stopOutputtingAudioDataPoints();
} catch (Exception e) {
e.printStackTrace();
}
startRecording.setVisibility(View.VISIBLE);
stopRecording.setVisibility(View.GONE);
recording = false;
short[] output;
output = new short[outData.size() * 32];
for(int i=0; i<outData.size(); i++){
for(int j=0; j<32; j++){
output[i] = outData.get(i)[j];
}
}
Intent intent = new Intent(ConnectDeviceActivity.this, AuscultationActivity.class);
intent.putExtra("output", output);
intent.putExtra("patient-id", patientId);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.i(AppConstants.TAG, "OUPUTLEN: " + output.length);
if(!stopped) {
stopped = true;
startActivity(intent);
}
}
});
return view;
}
//This overridden method makes DynamicWaveformViews avoid crashing
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
dynamicWaveformView = (DynamicWaveformView) view.findViewById(R.id.dynamic_waveform_view);
dynamicWaveformView.init();
mAudioThread = new HandlerThread("AudioThread");
mAudioThread.start();
mAudioHandler = new Handler(mAudioThread.getLooper());
//updateView again for consistency (mDeviceBroadcast may be too much but still works)
updateView(connected);
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mEkoDevice = new EkoDevice("DUMMY_DEVICE", "0");
buyNow = findViewById(R.id.buyNow);
back = findViewById(R.id.back_icon);
back.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
});
buyNow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.google.com"));
startActivity(browserIntent);
}
});
changeAudioAmplitudeScaleFactor(8);
mPlayerManager = new PlayerManager();
mPlayerManager.onCreate();
LibCore.getInstance(ConnectDeviceActivity.this).setFiltering(true);
}
при попытке разместить внизу "onCreate" возникает следующая ошибка:
PopupWindow $BadTokenException: невозможно добавить окно - нулевой токен недействителен
1 ответ
Что касается вашей ошибки
PopupWindow $BadTokenException: невозможно добавить окно - нулевой токен недействителен
Возможно, добавьте этот код в Activity onResume()
метод lifecykle вместо onCreate
если нужно запускать более одного раза
Переместите scanningThread
, BluetoothAdapter
а также LocalBroadcastManager
LibCore
все в onCreate(). 'OnCreateView()' должен иметь толькоview = inflater.inflate(R.layout.fragment_home_2, container, false);
В onCreate()
только инициировать материал, подключать представления локальных переменных и устанавливать clicklisteners
. Как и все разовые вещи. Переход от фрагмента к действию практически одинаков, поскольку у них одинаковые методы жизненного цикла.
Посмотрите это хорошее объяснение о шпаргалке-android-lifecycle-cheat-Sheet