use of androidx.annotation.NonNull in project Timber by naman14.
the class SubStyleSelectorFragment method showPurchaseDialog.
private void showPurchaseDialog() {
MaterialDialog dialog = new MaterialDialog.Builder(getActivity()).title("Purchase").content("This now playing style is available after a one time purchase of any amount. Support development and unlock this style?").positiveText("Support development").neutralText("Restore purchases").onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
startActivity(new Intent(getActivity(), DonateActivity.class));
dialog.dismiss();
}
}).onNeutral(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
Intent intent = new Intent(getActivity(), DonateActivity.class);
intent.putExtra("title", "Restoring purchases..");
intent.setAction("restore");
startActivity(intent);
dialog.dismiss();
}
}).show();
}
use of androidx.annotation.NonNull in project android by owncloud.
the class SynchronizeFolderOperation method fetchRemoteFolder.
/**
* Get list of files in folder from remote server.
*
* @param client {@link OwnCloudClient} instance used to access the server.
* @return Result of the fetch, including list of remote files in the synced folder.
* @throws OperationCancelledException
*/
@NonNull
private RemoteOperationResult<ArrayList<RemoteFile>> fetchRemoteFolder(OwnCloudClient client) throws OperationCancelledException {
Timber.d("Fetching list of files in " + mAccount.name + mRemotePath + ", if changed");
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
}
ReadRemoteFolderOperation readFolderOperation = new ReadRemoteFolderOperation(mRemotePath);
return readFolderOperation.execute(client);
}
use of androidx.annotation.NonNull in project Tusky by Vavassor.
the class NotificationsFragment method onCreateView.
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_timeline_notifications, container, false);
// from inflater to silence warning
@NonNull Context context = inflater.getContext();
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
boolean showNotificationsFilterSetting = preferences.getBoolean("showNotificationsFilter", true);
// Clear notifications on filter visibility change to force refresh
if (showNotificationsFilterSetting != showNotificationsFilter)
notifications.clear();
showNotificationsFilter = showNotificationsFilterSetting;
// Setup the SwipeRefreshLayout.
swipeRefreshLayout = rootView.findViewById(R.id.swipeRefreshLayout);
recyclerView = rootView.findViewById(R.id.recyclerView);
progressBar = rootView.findViewById(R.id.progressBar);
statusView = rootView.findViewById(R.id.statusView);
appBarOptions = rootView.findViewById(R.id.appBarOptions);
swipeRefreshLayout.setOnRefreshListener(this);
swipeRefreshLayout.setColorSchemeResources(R.color.tusky_blue);
loadNotificationsFilter();
// Setup the RecyclerView.
recyclerView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(context);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAccessibilityDelegateCompat(new ListStatusAccessibilityDelegate(recyclerView, this, (pos) -> {
NotificationViewData notification = notifications.getPairedItemOrNull(pos);
// We support replies only for now
if (notification instanceof NotificationViewData.Concrete) {
return ((NotificationViewData.Concrete) notification).getStatusViewData();
} else {
return null;
}
}));
recyclerView.addItemDecoration(new DividerItemDecoration(context, DividerItemDecoration.VERTICAL));
StatusDisplayOptions statusDisplayOptions = new StatusDisplayOptions(preferences.getBoolean("animateGifAvatars", false), accountManager.getActiveAccount().getMediaPreviewEnabled(), preferences.getBoolean("absoluteTimeView", false), preferences.getBoolean("showBotOverlay", true), preferences.getBoolean("useBlurhash", true), CardViewMode.NONE, preferences.getBoolean("confirmReblogs", true), preferences.getBoolean("confirmFavourites", false), preferences.getBoolean(PrefKeys.WELLBEING_HIDE_STATS_POSTS, false), preferences.getBoolean(PrefKeys.ANIMATE_CUSTOM_EMOJIS, false));
adapter = new NotificationsAdapter(accountManager.getActiveAccount().getAccountId(), dataSource, statusDisplayOptions, this, this, this);
alwaysShowSensitiveMedia = accountManager.getActiveAccount().getAlwaysShowSensitiveMedia();
alwaysOpenSpoiler = accountManager.getActiveAccount().getAlwaysOpenSpoiler();
recyclerView.setAdapter(adapter);
topLoading = false;
bottomLoading = false;
bottomId = null;
updateAdapter();
Button buttonClear = rootView.findViewById(R.id.buttonClear);
buttonClear.setOnClickListener(v -> confirmClearNotifications());
buttonFilter = rootView.findViewById(R.id.buttonFilter);
buttonFilter.setOnClickListener(v -> showFilterMenu());
if (notifications.isEmpty()) {
swipeRefreshLayout.setEnabled(false);
sendFetchNotificationsRequest(null, null, FetchEnd.BOTTOM, -1);
} else {
progressBar.setVisibility(View.GONE);
}
((SimpleItemAnimator) recyclerView.getItemAnimator()).setSupportsChangeAnimations(false);
updateFilterVisibility();
return rootView;
}
use of androidx.annotation.NonNull in project Tusky by Vavassor.
the class LinkHelper method setClickableText.
/**
* Finds links, mentions, and hashtags in a piece of text and makes them clickable, associating
* them with callbacks to notify when they're clicked.
*
* @param view the returned text will be put in
* @param content containing text with mentions, links, or hashtags
* @param mentions any '@' mentions which are known to be in the content
* @param listener to notify about particular spans that are clicked
*/
public static void setClickableText(TextView view, CharSequence content, @Nullable List<Status.Mention> mentions, final LinkListener listener) {
SpannableStringBuilder builder = SpannableStringBuilder.valueOf(content);
URLSpan[] urlSpans = builder.getSpans(0, content.length(), URLSpan.class);
for (URLSpan span : urlSpans) {
int start = builder.getSpanStart(span);
int end = builder.getSpanEnd(span);
int flags = builder.getSpanFlags(span);
CharSequence text = builder.subSequence(start, end);
ClickableSpan customSpan = null;
if (text.charAt(0) == '#') {
final String tag = text.subSequence(1, text.length()).toString();
customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override
public void onClick(@NonNull View widget) {
listener.onViewTag(tag);
}
};
} else if (text.charAt(0) == '@' && mentions != null && mentions.size() > 0) {
// https://github.com/tuskyapp/Tusky/pull/2339
String id = null;
for (Status.Mention mention : mentions) {
if (mention.getUrl().equals(span.getURL())) {
id = mention.getId();
break;
}
}
if (id != null) {
final String accountId = id;
customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override
public void onClick(@NonNull View widget) {
listener.onViewAccount(accountId);
}
};
}
}
if (customSpan == null) {
customSpan = new NoUnderlineURLSpan(span.getURL()) {
@Override
public void onClick(@NonNull View widget) {
listener.onViewUrl(getURL());
}
};
}
builder.removeSpan(span);
builder.setSpan(customSpan, start, end, flags);
/* Add zero-width space after links in end of line to fix its too large hitbox.
* See also : https://github.com/tuskyapp/Tusky/issues/846
* https://github.com/tuskyapp/Tusky/pull/916 */
if (end >= builder.length() || builder.subSequence(end, end + 1).toString().equals("\n")) {
builder.insert(end, "\u200B");
}
}
view.setText(builder);
view.setMovementMethod(LinkMovementMethod.getInstance());
}
use of androidx.annotation.NonNull in project kdeconnect-android by KDE.
the class SMSHelper method parseMMS.
/**
* Parse all parts of the MMS message into a message
* Original implementation from https://stackoverflow.com/a/6446831/3723163
*/
@NonNull
private static Message parseMMS(@NonNull Context context, @NonNull Map<String, String> messageInfo, @NonNull List<TelephonyHelper.LocalPhoneNumber> userPhoneNumbers) {
int event = Message.EVENT_UNKNOWN;
@NonNull String body = "";
long date;
int type;
int read = Integer.parseInt(messageInfo.get(Message.READ));
@NonNull ThreadID threadID = new ThreadID(Long.parseLong(messageInfo.get(Message.THREAD_ID)));
long uID = Long.parseLong(messageInfo.get(Message.U_ID));
int subscriptionID = NumberUtils.toInt(messageInfo.get(Message.SUBSCRIPTION_ID));
List<Attachment> attachments = new ArrayList<>();
String[] columns = { // The content ID of this part
Telephony.Mms.Part._ID, // The location in the filesystem of the data
Telephony.Mms.Part._DATA, // The mime type of the data
Telephony.Mms.Part.CONTENT_TYPE, // The plain text body of this MMS
Telephony.Mms.Part.TEXT, // Charset of the plain text body
Telephony.Mms.Part.CHARSET };
String mmsID = messageInfo.get(Message.U_ID);
String selection = Telephony.Mms.Part.MSG_ID + " = ?";
String[] selectionArgs = { mmsID };
// Get text body and attachments of the message
try (Cursor cursor = context.getContentResolver().query(getMMSPartUri(), columns, selection, selectionArgs, null)) {
if (cursor != null && cursor.moveToFirst()) {
int partIDColumn = cursor.getColumnIndexOrThrow(Telephony.Mms.Part._ID);
int contentTypeColumn = cursor.getColumnIndexOrThrow(Telephony.Mms.Part.CONTENT_TYPE);
int dataColumn = cursor.getColumnIndexOrThrow(Telephony.Mms.Part._DATA);
int textColumn = cursor.getColumnIndexOrThrow(Telephony.Mms.Part.TEXT);
do {
long partID = cursor.getLong(partIDColumn);
String contentType = cursor.getString(contentTypeColumn);
String data = cursor.getString(dataColumn);
if (MimeType.isTypeText(contentType)) {
if (data != null) {
// data != null means the data is on disk. Go get it.
body = getMmsText(context, partID);
} else {
body = cursor.getString(textColumn);
}
event = addEventFlag(event, Message.EVENT_TEXT_MESSAGE);
} else if (MimeType.isTypeImage(contentType)) {
String fileName = data.substring(data.lastIndexOf('/') + 1);
// Get the actual image from the mms database convert it into thumbnail and encode to Base64
Bitmap image = SmsMmsUtils.getMmsImage(context, partID);
Bitmap thumbnailImage = ThumbnailUtils.extractThumbnail(image, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
String encodedThumbnail = SmsMmsUtils.bitMapToBase64(thumbnailImage);
attachments.add(new Attachment(partID, contentType, encodedThumbnail, fileName));
} else if (MimeType.isTypeVideo(contentType)) {
String fileName = data.substring(data.lastIndexOf('/') + 1);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(context, ContentUris.withAppendedId(getMMSPartUri(), partID));
Bitmap videoThumbnail = retriever.getFrameAtTime();
String encodedThumbnail = SmsMmsUtils.bitMapToBase64(Bitmap.createScaledBitmap(videoThumbnail, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, true));
attachments.add(new Attachment(partID, contentType, encodedThumbnail, fileName));
} else if (MimeType.isTypeAudio(contentType)) {
String fileName = data.substring(data.lastIndexOf('/') + 1);
attachments.add(new Attachment(partID, contentType, null, fileName));
} else {
Log.v("SMSHelper", "Unsupported attachment type: " + contentType);
}
} while (cursor.moveToNext());
}
} catch (Exception e) {
e.printStackTrace();
}
// Determine whether the message was in- our out- bound
long messageBox = Long.parseLong(messageInfo.get(Telephony.Mms.MESSAGE_BOX));
if (messageBox == Telephony.Mms.MESSAGE_BOX_INBOX) {
type = Telephony.Sms.MESSAGE_TYPE_INBOX;
} else if (messageBox == Telephony.Mms.MESSAGE_BOX_SENT) {
type = Telephony.Sms.MESSAGE_TYPE_SENT;
} else {
// As an undocumented feature, it looks like the values of Mms.MESSAGE_BOX_*
// are the same as Sms.MESSAGE_TYPE_* of the same type. So by default let's just use
// the value we've got.
// This includes things like drafts, which are a far-distant plan to support
type = Integer.parseInt(messageInfo.get(Telephony.Mms.MESSAGE_BOX));
}
// Get address(es) of the message
MultimediaMessagePdu msg = getMessagePdu(context, uID);
Address from = SmsMmsUtils.getMmsFrom(msg);
List<Address> to = SmsMmsUtils.getMmsTo(msg);
List<Address> addresses = new ArrayList<>();
if (from != null) {
boolean isLocalPhoneNumber = userPhoneNumbers.stream().anyMatch(localPhoneNumber -> localPhoneNumber.isMatchingPhoneNumber(from.address));
if (!isLocalPhoneNumber && !from.toString().equals("insert-address-token")) {
addresses.add(from);
}
}
if (to != null) {
for (Address address : to) {
boolean isLocalPhoneNumber = userPhoneNumbers.stream().anyMatch(localPhoneNumber -> localPhoneNumber.isMatchingPhoneNumber(address.address));
if (!isLocalPhoneNumber && !from.toString().equals("insert-address-token")) {
addresses.add(address);
}
}
}
if (addresses.size() >= 2) {
event = addEventFlag(event, Message.EVENT_MULTI_TARGET);
}
// Canonicalize the date field
// SMS uses epoch milliseconds, MMS uses epoch seconds. Standardize on milliseconds.
long rawDate = Long.parseLong(messageInfo.get(Message.DATE));
date = rawDate * 1000;
return new Message(addresses, body, date, type, read, threadID, uID, event, subscriptionID, attachments);
}
Aggregations