If you are annoyed that "Sources for Android 26" are not yet available via SDK manager, this might be for you:
- Collect source files
mkdir android-sdk-source-build
cd android-sdk-source-build
mkdir -p frameworks/base| // based on: https://github.com/george-steel/android-utils/blob/master/src/org/oshkimaadziig/george/androidutils/SpanFormatter.java | |
| public class StringSpan { | |
| private static final Pattern PATTERN = Pattern.compile("%([^a-zA-z%]*)([[a-zA-Z%]&&[^tT]]|[tT][a-zA-Z])"); | |
| private StringSpan() { | |
| } | |
| public static CharSequence format(@NonNull CharSequence format, Object... args) { | |
| return format(Locale.getDefault(), format, args); |
| public class SupportVersion { | |
| private SupportVersion() { | |
| } | |
| public static boolean isLollipopOrAbove() { | |
| return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; | |
| } | |
| public static boolean isMarshmallowOrAbove() { | |
| return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M; |
If you are annoyed that "Sources for Android 26" are not yet available via SDK manager, this might be for you:
mkdir android-sdk-source-build
cd android-sdk-source-build
mkdir -p frameworks/base| #!/bin/bash | |
| SOURCE=$1 | |
| if [[ -z $SOURCE ]]; then | |
| echo "Usage: $0 [source]" >&2 | |
| exit | |
| fi | |
| sudo mkdir -p /mnt/sd1 |
| abstract class BaseActivity<MODEL : BaseModel<Bundle>, VIEW : BaseView, out PRESENTER : BasePresenter<MODEL, VIEW>> : KoinActivity() { | |
| protected abstract val presenter: PRESENTER | |
| override fun onCreate(savedInstanceState: Bundle?) { | |
| super.onCreate(savedInstanceState) | |
| val arguments = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments | |
| val model = Class.forName(arguments.first().javaClass.toString().split(" ").last()).newInstance() | |
| presenter.bind(model as MODEL, this as VIEW) | |
| } |
| # change resolution | |
| ffmpeg -i video_1920.mp4 -vf scale=300:534 video_300.mp4 | |
| # convert | |
| ffmpeg -i video_300.mp4 final.gif |
| class ClearableAutoCompleteTextView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, | |
| defStyleAttr: Int = android.R.attr.editTextStyle) | |
| : AutoCompleteTextView(context, attrs, defStyleAttr) { | |
| private val clearDrawable: Drawable? = ContextCompat.getDrawable(context, R.drawable.ic_clear) | |
| init { | |
| clearDrawable?.setBounds(0, 0, clearDrawable.intrinsicWidth, clearDrawable.intrinsicHeight) | |
| setOnTouchListener { _, event -> | |
| if (isClearDrawableVisible() && event.action == MotionEvent.ACTION_UP) { |
| inline fun TextView.textWatcher(init: CustomTextWatcher.() -> Unit) = addTextChangedListener(CustomTextWatcher().apply(init)) | |
| @Suppress("unused") | |
| class CustomTextWatcher : TextWatcher { | |
| private var _beforeTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null | |
| private var _onTextChanged: ((CharSequence?, Int, Int, Int) -> Unit)? = null | |
| private var _afterTextChanged: ((Editable?) -> Unit)? = null | |
| private var _beforeTextChangedShout: (() -> Unit)? = null | |
| private var _onTextChangedShout: (() -> Unit)? = null |
| object Bus { | |
| // val event = Event<Any>() | |
| } | |
| class Event<TYPE> { | |
| private val handlers = arrayListOf<((TYPE) -> Unit)>() | |
| operator fun plusAssign(handler: (TYPE) -> Unit) { | |
| handlers.add(handler) | |
| } |
| fun String.encodeBase64ToString(): String = String(this.toByteArray().encodeBase64()) | |
| fun String.encodeBase64ToByteArray(): ByteArray = this.toByteArray().encodeBase64() | |
| fun ByteArray.encodeBase64ToString(): String = String(this.encodeBase64()) | |
| fun String.decodeBase64(): String = String(this.toByteArray().decodeBase64()) | |
| fun String.decodeBase64ToByteArray(): ByteArray = this.toByteArray().decodeBase64() | |
| fun ByteArray.decodeBase64ToString(): String = String(this.decodeBase64()) | |
| fun ByteArray.encodeBase64(): ByteArray { | |
| val table = (CharRange('A', 'Z') + CharRange('a', 'z') + CharRange('0', '9') + '+' + '/').toCharArray() |