The line in which i am getting the error:
public class OpenChatFragment extends Fragment {
private static final String LOG_TAG = OpenChatFragment.class.getSimpleName();
private static final int CHANNEL_LIST_LIMIT = 30;
private static final String CONNECTION_HANDLER_ID = "CONNECTION_HANDLER_OPEN_CHAT";
private static final String CHANNEL_HANDLER_ID = "CHANNEL_HANDLER_OPEN_CHAT";
private static final int STATE_NORMAL = 0;
private static final int STATE_EDIT = 1;
private static final int INTENT_REQUEST_CHOOSE_IMAGE = 300;
private static final int PERMISSION_WRITE_EXTERNAL_STORAGE = 13;
static final String EXTRA_CHANNEL_URL = "CHANNEL_URL";
private InputMethodManager mIMM;
private RecyclerView mRecyclerView;
private OpenChatAdapter mChatAdapter;
private LinearLayoutManager mLayoutManager;
private View mRootLayout;
private EditText mMessageEditText;
private Button mMessageSendButton;
private ImageButton mUploadFileButton;
private View mCurrentEventLayout;
private TextView mCurrentEventText;
private OpenChannel mChannel;
private String mChannelUrl;
private PreviousMessageListQuery mPrevMessageListQuery;
private int mCurrentState = STATE_NORMAL;
private BaseMessage mEditingMessage = null;
/**
* To create an instance of this fragment, a Channel URL should be passed.
*/
public static OpenChatFragment newInstance(@NonNull String channelUrl) {
OpenChatFragment fragment = new OpenChatFragment();
Bundle args = new Bundle();
args.putString(Sendbird.EXTRA_OPEN_CHANNEL_URL, channelUrl);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mIMM = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_open_chat, container, false);
setRetainInstance(true);
setHasOptionsMenu(true);
mRootLayout = rootView.findViewById(R.id.layout_open_chat_root);
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_open_channel_chat);
mCurrentEventLayout = rootView.findViewById(R.id.layout_open_chat_current_event);
mCurrentEventText = (TextView) rootView.findViewById(R.id.text_open_chat_current_event);
// String username = mChannel.getName();
// Log.d(“username”,username);
setUpChatAdapter();
setUpRecyclerView();
// Set up chat box
mMessageSendButton = (Button) rootView.findViewById(R.id.button_open_channel_chat_send);
mMessageEditText = (EditText) rootView.findViewById(R.id.edittext_chat_message);
mMessageEditText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (s.length() > 0) {
mMessageSendButton.setEnabled(true);
} else {
mMessageSendButton.setEnabled(false);
}
}
});
mMessageSendButton.setEnabled(false);
mMessageSendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mCurrentState == STATE_EDIT) {
String userInput = mMessageEditText.getText().toString();
if (userInput.length() > 0) {
if (mEditingMessage != null) {
editMessage(mEditingMessage, mMessageEditText.getText().toString());
}
}
setState(STATE_NORMAL, null, -1);
} else {
String userInput = mMessageEditText.getText().toString();
if (userInput.length() > 0) {
*here is the send message userinput where i am getting the null pointer exception mchannel is not being initialized*
/// sendUserMessage(userInput);
mMessageEditText.setText("");
}
}
}
});
mUploadFileButton = (ImageButton) rootView.findViewById(R.id.button_open_channel_chat_upload);
mUploadFileButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
requestImage();
}
});
// Gets channel from URL user requested
mChannelUrl = getArguments().getString(Sendbird.EXTRA_OPEN_CHANNEL_URL);
return rootView;
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case PERMISSION_WRITE_EXTERNAL_STORAGE:
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted.
Snackbar.make(mRootLayout, "Storage permissions granted. You can now upload or download files.",
Snackbar.LENGTH_LONG)
.show();
} else {
// Permission denied.
Snackbar.make(mRootLayout, "Permissions denied.",
Snackbar.LENGTH_SHORT)
.show();
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Set this as true to restart auto-background detection.
// This means that you will be automatically disconnected from SendBird when your
// app enters the background.
SendBird.setAutoBackgroundDetection(true);
if (requestCode == INTENT_REQUEST_CHOOSE_IMAGE && resultCode == Activity.RESULT_OK) {
if (data == null) {
Log.d(LOG_TAG, "data is null!");
return;
}
showUploadConfirmDialog(data.getData());
}
}
@Override
public void onResume() {
super.onResume();
ConnectionManager.addConnectionManagementHandler(CONNECTION_HANDLER_ID, new ConnectionManager.ConnectionManagementHandler() {
@Override
public void onConnected(boolean reconnect) {
if (reconnect) {
refresh();
} else {
refreshFirst();
}
}
});
SendBird.addChannelHandler(CHANNEL_HANDLER_ID, new SendBird.ChannelHandler() {
@Override
public void onMessageReceived(BaseChannel baseChannel, BaseMessage baseMessage) {
// Add new message to view
if (baseChannel.getUrl().equals(mChannelUrl)) {
mChatAdapter.addFirst(baseMessage);
}
}
@Override
public void onMessageDeleted(BaseChannel baseChannel, long msgId) {
super.onMessageDeleted(baseChannel, msgId);
if (baseChannel.getUrl().equals(mChannelUrl)) {
mChatAdapter.delete(msgId);
}
}
@Override
public void onMessageUpdated(BaseChannel channel, BaseMessage message) {
super.onMessageUpdated(channel, message);
if (channel.getUrl().equals(mChannelUrl)) {
mChatAdapter.update(message);
}
}
});
}
@Override
public void onPause() {
ConnectionManager.removeConnectionManagementHandler(CONNECTION_HANDLER_ID);
SendBird.removeChannelHandler(CHANNEL_HANDLER_ID);
super.onPause();
}
@Override
public void onDestroyView() {
if (mChannel != null) {
mChannel.exit(new OpenChannel.OpenChannelExitHandler() {
@Override
public void onResult(SendBirdException e) {
if (e != null) {
// Error!
e.printStackTrace();
return;
}
}
});
}
super.onDestroyView();
}
// @Override
// public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// inflater.inflate(R.menu.menu_open_chat, menu);
// super.onCreateOptionsMenu(menu, inflater);
// }
// @Override
// public boolean onOptionsItemSelected(MenuItem item) {
// int id = item.getItemId();
//
// if (id == R.id.action_open_chat_view_participants) {
// Intent intent = new Intent(getActivity(), ParticipantListActivity.class);
// intent.putExtra(EXTRA_CHANNEL_URL, mChannel.getUrl());
// startActivity(intent);
//
// return true;
// }
//
// return super.onOptionsItemSelected(item);
// }
private void setUpChatAdapter() {
mChatAdapter = new OpenChatAdapter(getActivity());
mChatAdapter.setOnItemClickListener(new OpenChatAdapter.OnItemClickListener() {
@Override
public void onUserMessageItemClick(UserMessage message) {
}
@Override
public void onFileMessageItemClick(FileMessage message) {
onFileMessageClicked(message);
}
@Override
public void onAdminMessageItemClick(AdminMessage message) {
}
});
mChatAdapter.setOnItemLongClickListener(new OpenChatAdapter.OnItemLongClickListener() {
@Override
public void onUserMessageItemLongClick(UserMessage message, int position) {
if (message.getSender().getUserId().equals(PrefrenceUtil.getUserId())) {
showMessageOptionsDialog(message, position);
}
}
@Override
public void onFileMessageItemLongClick(FileMessage message) {
}
@Override
public void onAdminMessageItemLongClick(AdminMessage message) {
}
});
}
private void showMessageOptionsDialog(final BaseMessage message, final int position) {
String[] options = new String[] { "Edit message", "Delete message" };
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
setState(STATE_EDIT, message, position);
} else if (which == 1) {
deleteMessage(message);
}
}
});
builder.create().show();
}
private void setState(int state, BaseMessage editingMessage, final int position) {
switch (state) {
case STATE_NORMAL:
mCurrentState = STATE_NORMAL;
mEditingMessage = null;
mUploadFileButton.setVisibility(View.VISIBLE);
mMessageSendButton.setText("SEND");
mMessageEditText.setText("");
break;
case STATE_EDIT:
mCurrentState = STATE_EDIT;
mEditingMessage = editingMessage;
mUploadFileButton.setVisibility(View.GONE);
mMessageSendButton.setText("SAVE");
String messageString = ((UserMessage)editingMessage).getMessage();
if (messageString == null) {
messageString = "";
}
mMessageEditText.setText(messageString);
if (messageString.length() > 0) {
mMessageEditText.setSelection(0, messageString.length());
}
mMessageEditText.requestFocus();
mMessageEditText.postDelayed(new Runnable() {
@Override
public void run() {
mIMM.showSoftInput(mMessageEditText, 0);
mRecyclerView.postDelayed(new Runnable() {
@Override
public void run() {
mRecyclerView.scrollToPosition(position);
}
}, 500);
}
}, 100);
break;
}
}
// @Override
// public void onAttach(Context context) {
// super.onAttach(context);
// ((OpenChannelActivity)context).setOnBackPressedListener(new OpenChannelActivity.onBackPressedListener() {
// @Override
// public boolean onBack() {
// if (mCurrentState == STATE_EDIT) {
// setState(STATE_NORMAL, null, -1);
// return true;
// }
//
// mIMM.hideSoftInputFromWindow(mMessageEditText.getWindowToken(), 0);
// return false;
// }
// });
// }
private void setUpRecyclerView() {
mLayoutManager = new LinearLayoutManager(getActivity());
mLayoutManager.setReverseLayout(true);
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setAdapter(mChatAdapter);
// Load more messages when user reaches the top of the current message list.
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (mLayoutManager.findLastVisibleItemPosition() == mChatAdapter.getItemCount() - 1) {
loadNextMessageList(CHANNEL_LIST_LIMIT);
}
Log.v(LOG_TAG, "onScrollStateChanged");
}
});
}
private void onFileMessageClicked(FileMessage message) {
String type = message.getType().toLowerCase();
if (type.startsWith("image")) {
Intent i = new Intent(getActivity(), PhotoViewerActivity.class);
i.putExtra("url", message.getUrl());
i.putExtra("type", message.getType());
startActivity(i);
} else if (type.startsWith("video")) {
Intent intent = new Intent(getActivity(), MediaPlayerActivity.class);
intent.putExtra("url", message.getUrl());
startActivity(intent);
} else {
showDownloadConfirmDialog(message);
}
}
private void showDownloadConfirmDialog(final FileMessage message) {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// If storage permissions are not granted, request permissions at run-time,
// as per < API 23 guidelines.
requestStoragePermissions();
} else {
new AlertDialog.Builder(getActivity())
.setMessage("Download file?")
.setPositiveButton(R.string.download, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
FileUtils.downloadFile(getActivity(), message.getUrl(), message.getName());
}
}
})
.setNegativeButton(R.string.cancel, null).show();
}
}
private void showUploadConfirmDialog(final Uri uri) {
new AlertDialog.Builder(getActivity())
.setMessage("Upload file?")
.setPositiveButton(R.string.upload, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (which == DialogInterface.BUTTON_POSITIVE) {
// Specify two dimensions of thumbnails to generate
List<FileMessage.ThumbnailSize> thumbnailSizes = new ArrayList<>();
thumbnailSizes.add(new FileMessage.ThumbnailSize(240, 240));
thumbnailSizes.add(new FileMessage.ThumbnailSize(320, 320));
sendImageWithThumbnail(uri, thumbnailSizes);
}
}
})
.setNegativeButton(R.string.cancel, null).show();
}
private void requestImage() {
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// If storage permissions are not granted, request permissions at run-time,
// as per < API 23 guidelines.
requestStoragePermissions();
} else {
Intent intent = new Intent();
// Show only images, no videos or anything else
intent.setType("image/* video/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
// Always show the chooser (if there are multiple options available)
startActivityForResult(Intent.createChooser(intent, "Select Media"), INTENT_REQUEST_CHOOSE_IMAGE);
// Set this as false to maintain connection
// even when an external Activity is started.
SendBird.setAutoBackgroundDetection(false);
}
}
private void requestStoragePermissions() {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Provide an additional rationale to the user if the permission was not granted
// and the user would benefit from additional context for the use of the permission.
// For example if the user has previously denied the permission.
Snackbar.make(mRootLayout, "Storage access permissions are required to upload/download files.",
Snackbar.LENGTH_LONG)
.setAction("Okay", new View.OnClickListener() {
@Override
public void onClick(View view) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_WRITE_EXTERNAL_STORAGE);
}
})
.show();
} else {
// Permission has not been granted yet. Request it directly.
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_WRITE_EXTERNAL_STORAGE);
}
}
private void refreshFirst() {
enterChannel(mChannelUrl);
}
/**
* Enters an Open Channel.
* <p>
* A user must successfully enter a channel before being able to load or send messages
* within the channel.
*
* @param channelUrl The URL of the channel to enter.
*/
private void enterChannel(String channelUrl) {
OpenChannel.getChannel(channelUrl, new OpenChannel.OpenChannelGetHandler() {
@Override
public void onResult(final OpenChannel openChannel, SendBirdException e) {
if (e != null) {
// Error!
e.printStackTrace();
return;
}
// Enter the channel
openChannel.enter(new OpenChannel.OpenChannelEnterHandler() {
@Override
public void onResult(SendBirdException e) {
if (e != null) {
// Error!
e.printStackTrace();
return;
}
mChannel = openChannel;
//
// if (getActivity() != null) {
// // Set action bar title to name of channel
// // ((OpenChannelActivity) getActivity()).setActionBarTitle(mChannel.getName());
// }
refresh();
}
});
}
});
}
private void sendUserMessage(String text) {
String username = mChannel.getName();
Log.d("username",username);
mChannel.sendUserMessage(text, new BaseChannel.SendUserMessageHandler() {
@Override
public void onSent(UserMessage userMessage, SendBirdException e) {
if (e != null) {
// Error!
Log.e(LOG_TAG, e.toString());
if (getActivity() != null) {
Toast.makeText(getActivity(),
"Send failed with error" + e.getCode() + ": " + e.getMessage(), Toast.LENGTH_SHORT)
.show();
}
return;
}
// Display sent message to RecyclerView
mChatAdapter.addFirst(userMessage);
}
});
}
/**
* Sends a File Message containing an image file.
* Also requests thumbnails to be generated in specified sizes.
*
* @param uri The URI of the image, which in this case is received through an Intent request.
*/
private void sendImageWithThumbnail(Uri uri, List<FileMessage.ThumbnailSize> thumbnailSizes) {
Hashtable<String, Object> info = FileUtils.getFileInfo(getActivity(), uri);
if (info == null || info.isEmpty()) {
Toast.makeText(getActivity(), "Extracting file information failed.", Toast.LENGTH_LONG).show();
return;
}
final String name;
if (info.containsKey("name")) {
name = (String) info.get("name");
} else {
name = "SendBird File";
}
final String path = (String) info.get("path");
final File file = new File(path);
final String mime = (String) info.get("mime");
final int size = (Integer) info.get("size");
if (path == null || path.equals("")) {
Toast.makeText(getActivity(), "File must be located in local storage.", Toast.LENGTH_LONG).show();
} else {
// Send image with thumbnails in the specified dimensions
mChannel.sendFileMessage(file, name, mime, size, "", null, thumbnailSizes, new BaseChannel.SendFileMessageHandler() {
@Override
public void onSent(FileMessage fileMessage, SendBirdException e) {
if (e != null) {
if (getActivity() != null) {
Toast.makeText(getActivity(), "" + e.getCode() + ":" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
return;
}
mChatAdapter.addFirst(fileMessage);
}
});
}
}
private void refresh() {
loadInitialMessageList(CHANNEL_LIST_LIMIT);
}
/**
* Replaces current message list with new list.
* Should be used only on initial load.
*/
private void loadInitialMessageList(int numMessages) {
mPrevMessageListQuery = mChannel.createPreviousMessageListQuery();
mPrevMessageListQuery.load(numMessages, true, new PreviousMessageListQuery.MessageListQueryResult() {
@Override
public void onResult(List<BaseMessage> list, SendBirdException e) {
if (e != null) {
// Error!
e.printStackTrace();
return;
}
mChatAdapter.setMessageList(list);
}
});
}
/**
* Loads messages and adds them to current message list.
* <p>
* A PreviousMessageListQuery must have been already initialized through {@link #loadInitialMessageList(int)}
*/
private void loadNextMessageList(int numMessages) throws NullPointerException {
if (mChannel == null) {
throw new NullPointerException("Current channel instance is null.");
}
if (mPrevMessageListQuery == null) {
throw new NullPointerException("Current query instance is null.");
}
mPrevMessageListQuery.load(numMessages, true, new PreviousMessageListQuery.MessageListQueryResult() {
@Override
public void onResult(List<BaseMessage> list, SendBirdException e) {
if (e != null) {
// Error!
e.printStackTrace();
return;
}
for (BaseMessage message : list) {
mChatAdapter.addLast((message));
}
}
});
}
private void editMessage(final BaseMessage message, String editedMessage) {
mChannel.updateUserMessage(message.getMessageId(), editedMessage, null, null, new BaseChannel.UpdateUserMessageHandler() {
@Override
public void onUpdated(UserMessage userMessage, SendBirdException e) {
if (e != null) {
// Error!
Toast.makeText(getActivity(), "Error " + e.getCode() + ": " + e.getMessage(), Toast.LENGTH_SHORT).show();
return;
}
refresh();
}
});
}
/**
* Deletes a message within the channel.
* Note that users can only delete messages sent by oneself.
*
* @param message The message to delete.
*/
private void deleteMessage(final BaseMessage message) {
// mChannel.deleteMessage(message, new BaseChannel.DeleteMessageHandler() {
// @Override
// public void onResult(SendBirdException e) {
//
// }
// });
mChannel.deleteMessage(message, new BaseChannel.DeleteMessageHandler() {
@Override
public void onResult(SendBirdException e) {
if (e != null) {
// Error!
Toast.makeText(getActivity(), "Error " + e.getCode() + ": " + e.getMessage(), Toast.LENGTH_SHORT).show();
return;
}
refresh();
}
});
}
}