1
The problem is this: I have two fragments, the first has a list, which if clicked, sends an object to be edited in fragment B. In fragment A there is also an inclusion button that when clicked opens fragment B to register certain information. The code of fragment A is this:
public class AlarmFragment extends Fragment {
private OnFragmentInteractionListener mListener;
private ListView lista;
FloatingActionButton btnAddAlarme;
public AlarmFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_alarm, container, false);
TimerDAO dao = new TimerDAO(getActivity());
List<Timer> timers = dao.getListaAgendamentos();
dao.close();
int layout = android.R.layout.simple_list_item_1;
ListaAgendamentosCadastradosAdapter adapter = new ListaAgendamentosCadastradosAdapter(timers, layout, getActivity());
//ArrayAdapter<Timer> adapter = new ArrayAdapter<Timer>(getActivity(), layout, timers);
lista = (ListView)view.findViewById(R.id.listaAgendamentosCadastrados);
lista.setAdapter(adapter);
lista.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Timer agendamentoClicado = (Timer)parent.getItemAtPosition(position);
CadastroAlarmFragment cadastroAlarmFragment = new CadastroAlarmFragment();
Bundle args = new Bundle();
args.putSerializable("agendamentoSelecionado", agendamentoClicado);
cadastroAlarmFragment.setArguments(args);
FragmentManager manager = getFragmentManager();
manager.beginTransaction().replace(R.id.content_main, cadastroAlarmFragment, cadastroAlarmFragment.getTag()).commit();
}
});
btnAddAlarme = (FloatingActionButton) view.findViewById(R.id.btnAddAlarme);
btnAddAlarme.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
CadastroAlarmFragment cadastroAlarmFragment = new CadastroAlarmFragment();
FragmentManager manager = getFragmentManager();
manager.beginTransaction().replace(
R.id.content_main,
cadastroAlarmFragment,
cadastroAlarmFragment.getTag()
).commit();
}
});
return view;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
void onFragmentInteraction(Uri uri);
}
}
Following the searches on the Internet, I send the already existing object from fragment A to fragment B through a Serializable. When the second fragment is opened, I perform a check to see if what came through serializable is an object to be edited or if I need to register a new one. The code of fragment B is as follows::
public class CadastroAlarmFragment extends Fragment {
TextView txt_idAgendamento;
AlarmManager alarmManager;
TextClock tcHoraAtual;
Spinner cbSelecaoValvulaCadastroAgendamento;
EditText etTempoDeFuncionamentoCadastroAgendamento;
Button btnSalvaAgendamento;
ToggleButton btnAtivaAgendamento;
Long milli;
String actualTime;
Boolean clickTime = false;
Context context;
PendingIntent pendingIntent;
int hour, minute;
String horaMinuto;
public CadastroAlarmHelper helper;
public CadastroAlarmFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@RequiresApi(api = Build.VERSION_CODES.N)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_cadastro_alarm2, container, false);
helper = new CadastroAlarmHelper(view);
tcHoraAtual = (TextClock)view.findViewById(R.id.tcHoraAtual);
cbSelecaoValvulaCadastroAgendamento = (Spinner)view.findViewById(R.id.cbSelecaoValvulaCadastroAgendamento);
etTempoDeFuncionamentoCadastroAgendamento = (EditText)view.findViewById(R.id.etTempoDeFuncionamentoCadastroAgendamento);
btnSalvaAgendamento = (Button)view.findViewById(R.id.btnSalvaAgendamento);
btnAtivaAgendamento = (ToggleButton)view.findViewById(R.id.btnAtivaAgendamento);
txt_idAgendamento = (TextView)view.findViewById(R.id.txt_idAgendamento);
Bundle bundle = getArguments();
final Timer agendamentoParaSerAlterado = (Timer)bundle.getSerializable("agendamentoSelecionado");
if(agendamentoParaSerAlterado!= null)
{
btnSalvaAgendamento.setText("Salvar Alterações");
helper.colocaAgendamentoNaTela(agendamentoParaSerAlterado);
tcHoraAtual.setText(agendamentoParaSerAlterado.getDataHoraInicio());
}
else if(agendamentoParaSerAlterado == null){
tcHoraAtual.setFormat24Hour(getTime());
}
this.context = getActivity();
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
TimePickerFragment timePickerFragment = new TimePickerFragment();
//Cria a instancia do calendario
final java.util.Calendar calendar = timePickerFragment.calendar;
//Criando Intent pra classe AlarmReceiver
final Intent intent = new Intent(this.context, AlarmReceiver.class);
loadSpinnerData();
tcHoraAtual.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clickTime = true;
DialogFragment newFragment = new TimePickerFragment();
newFragment.show(getActivity().getFragmentManager(), "TIMEPICKER");
}
});
btnSalvaAgendamento.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String tempo = etTempoDeFuncionamentoCadastroAgendamento.getText().toString();
if(tempo.isEmpty()){
Toast.makeText(getActivity(), "Digite o tempo de funcionamento!", Toast.LENGTH_SHORT).show();
}
else{
Timer timer = helper.pegaInfoIrrigacaoCadastro();
TimerDAO dao = new TimerDAO(getActivity());
if(horaMinuto!=null) {
horaMinuto = tcHoraAtual.getText().toString();
hour = Integer.parseInt(horaMinuto.substring(0, 2));
minute = Integer.parseInt(horaMinuto.substring(3, 5));
}
else if(agendamentoParaSerAlterado == null)
{
calendar.set(java.util.Calendar.HOUR_OF_DAY, hour);
calendar.set(java.util.Calendar.MINUTE, minute);
final int _id = ((int)System.currentTimeMillis())*-1;
txt_idAgendamento.setText(String.valueOf(_id));
intent.putExtra("extra", "on"+tempo);
pendingIntent = PendingIntent.getBroadcast(getActivity(), _id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Definir o AlarmManager
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
dao.salvaTimer(timer);
}
else{
agendamentoParaSerAlterado.setId(agendamentoParaSerAlterado.getId());
dao.alteraTimer(timer);
Toast.makeText(getActivity(), "Alterações Salvas!", Toast.LENGTH_SHORT);
}
dao.close();
AlarmFragment alarmFragment = new AlarmFragment();
FragmentManager manager = getFragmentManager();
manager.beginTransaction().replace(
R.id.content_main,
alarmFragment,
alarmFragment.getTag()
).commit();
}
}
});
btnAtivaAgendamento.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
}
else {
String idAgendamento = (String) txt_idAgendamento.getText();
int _idAgendamento = Integer.valueOf(idAgendamento);
alarmManager.cancel(PendingIntent.getBroadcast(getActivity(), _idAgendamento, intent, PendingIntent.FLAG_CANCEL_CURRENT));
//put extra string into intent
//Tells the clock that youpressed "cancelar alarme"
intent.putExtra("extra","off");
//Para a musica
context.sendBroadcast(intent);
}
}
});
return view;
}
@RequiresApi(api = Build.VERSION_CODES.N)
public String getTime()
{
milli = System.currentTimeMillis();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date result = new Date(milli);
actualTime = sdf.format(result);
return actualTime;
}
private void loadSpinnerData()
{
TimerDAO dao = new TimerDAO(getActivity());
Cursor servicesCursor = dao.getServicesCursor();
String[]from = {"nomeValvula"};
int[] to ={android.R.id.text1};
SimpleCursorAdapter dataAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_spinner_dropdown_item, servicesCursor, from, to, 0);
cbSelecaoValvulaCadastroAgendamento.setAdapter(dataAdapter);
}
}
However, whenever I click the "new" button on Fragment A, Serializable is not sent, and when fragment B starts, it is checked if it is an object to be edited or if it is a new one. When this happens the system gives me the following error:
FATAL EXCEPTION: main
Process: com.example.cabral.irriga, PID: 24858
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.Serializable android.os.Bundle.getSerializable(java.lang.String)' on a null object reference
at com.example.cabral.irriga.CadastroAlarmFragment.onCreateView(CadastroAlarmFragment.java:90)
Which is exactly in the check where I need to know if it is a new one, or if it is to be edited, since Serializable is empty the error happens. So is there any other way for me to accomplish this task? Since in Activities can I send an empty Internet and do the same job tried above? Any other suggestions to solve the case?
Try to get your argument like this:
final Timer agendamentoParaSerAlterado = (Timer)getActivity().getIntent().getSerializableExtra("agendamentoSelecionado");
– viana
It worked, man! Thank you very much!
– Rodrigo Cabral
I put an answer Rodrigo. Hugs. Good luck!
– viana
For compilation purposes it worked, but in practice it did not. null Pointer doesn’t happen anymore, but I’m not getting any Intent on fragment B. How to send this input to fragment?
– Rodrigo Cabral
Are you debugging? What error is happening now?
– viana
Yes, I am debugging. What happens now is that the object is not being passed from Fragment A to Fragment B. The snippet: Schedule timePare Changed = Timer)getActivity(). getIntent(). getSerializableExtra("agend mentSelected"); Always receiving Null.
– Rodrigo Cabral
Try to pass it off:
context.getIntent().putExtra("agendamentoSelecionado", agendamentoClicado)
in Fragment A– viana
Even creating a context and making it receive this.context inside the fragment constructor A. The compiler presents: Cannot resolve method 'getIntent();'
– Rodrigo Cabral
Man, I looked right here and I realized there’s no problem with your
serializable
. The way it was, it works correctly. Try to notice if by clicking the button, if you are really sent aTimer
. Make sure you are able to pick up the item correctly through thegetItemAtPosition
. I’m suspecting that really nothing is passing. I advise on your fragment B you put a check, for exampleif (bundle != null)
– viana
I returned to the initial form, and to the initial problem as well. When it is an existing item the
getItemAtPosition
works perfectly and the line:final Timer agendamentoParaSerAlterado = (Timer)args.getSerializable("agendamentoSelecionado");
also. The problem is that if I do a check likeif(bundle != null)
and declare the above line within thisif
the code stops working because there are methods further down that use the variableagendamentoParaSerAlterado
. And if I declare it global, it needs to be final, and beingfinal
i can’t assign value to it within the if.– Rodrigo Cabral
Well, I took exactly the part that you send and the part that you receive the data through the
serializable
and worked perfectly by passing some other object. I think your problem here is something else that has nothing to do with theserializable
. Particularly I see no problem you create a global variable and check thebundle
is only to know if the problem is in theserializable
or problem in the object you are sending. I don’t think I can help much because there is no way to reproduce all code here.– viana
Thank you for the strength, but I solved it as follows: On the Fragment A inclusion button I sent a String on
bundle
to ensure that it was not null, and in Fragment B I kept my code, only verifying that the object was null. If it is, then register a new one, if the object is filled then edit the object. Anyway, thank you so much for the effort and for the help!– Rodrigo Cabral