After upgrading to LineageOS 17.1 I wasn’t able to play any audio via bluetooth connection from my Xiaomi Mi 8.
To fix this issue, just go to developer options and disable Bluetooth-AD2P-Hardware-Offload
and reboot your phone.
[Android] Upgrading LineageOS 16.0 to 17.1 on my Xiaomi Mi 8 (dipper)
Install the Android Debug Bridge (ADB)
https://wiki.lineageos.org/adb_fastboot_guide.html
https://github.com/M0Rf30/android-udev-rules#installation
# check if device is found
adb devices
# reboot into sideload modus
adb reboot sideload
Or manually boot into TWRP recovery, holding Volume Up + Power when the phone is off. Navigate to Advanced
-> ADB Sideload
.
Update MIUI Firmware
If your current MIUI Firmware does not support Android 10, you have to update it first.
Download the newest MIUI Firmware for your device from https://xiaomifirmwareupdater.com/firmware/dipper/.
Flash the new Firmware via TWRP or via ADB sideload.
adb sideload Downloads/fw_dipper_miui_MI8Global_V12.0.2.0.QEAMIXM_4e38c51916_10.0.zip
Download and flash new LineageOS image
I’m using the LineageOS fork LineageOS for microG. Download it from here: https://download.lineage.microg.org/dipper/ (MI 8 = dipper)
The upgrade steps are the same as for the official rom: https://wiki.lineageos.org/devices/dipper/upgrade. In my case only flashing the new image.
adb sideload Downloads/lineage-17.1-20210327-microG-dipper.zip
[ZFS] Activate/deactivate readonly property on dataset
# get readonly property
zfs get all | grep readonly
# deactivate readonly
zfs set readonly=off rpool/dataset
# activate readonly
zfs set readonly=on rpool/dataset
[ABAP] Parse SF Entity Key from URI
METHOD get_entitykey_from_uri.
" Pattern: Entity\((.*)\),
DATA(pattern) = iv_entity && `\((.*)\)`.
TRY.
DATA(matcher) = cl_abap_matcher=>create( pattern = pattern
text = iv_uri
ignore_case = abap_true ).
CATCH cx_sy_invalid_regex.
ENDTRY.
TRY.
DATA(lt_matches) = matcher->find_all( ).
ASSIGN lt_matches[ 1 ] TO FIELD-SYMBOL(<s>).
rv_entity_key = substring( val = iv_uri off = <s>-offset len = <s>-length ).
CATCH cx_sy_no_current_match.
ENDTRY.
ENDMETHOD.
[TrueNAS] Replacing failed disk
Yesterday I got a mail about a failed disk in my TrueNAS system.
So I logged in and checked the Alerts and also zpool status
.
Luckily I had an unused disk lying around. So just did a quick look in the TrueNAS Wiki (https://www.truenas.com/docs/hub/tasks/advanced/disk-replace/) and switched the drives…
After 5 minutes everything was done and the resilvering started.
It took about 4 hours for the 3TB disk. A zool clear poolname
removes the error message and the pool was back online.
Hermetosphäre
Blog von Ulf Soltau: https://ulfsoltau.wordpress.com/
Überblick geeigneter Pflanzen: https://www.dropbox.com/s/0o5ednj25hfjcf8/Pflanzen%20f%C3%BCr%20die%20Hermetosph%C3%A4re%20%281%29.xls?dl=0
Pflanzen bestellen: bens-jungle.com/ und terra-erfordia.de/
Interessantes Experiment: Biosphäre 2
[Deutsch] Synonyme für gut
nicht ganz so gut wie “gut” | besser als “gut” |
---|---|
achtbar | ausgezeichnet |
angebracht | außergewöhnlich |
angemessen | außerordentlich |
angenehm | beeindruckend |
ansehnlich | beispielhaft |
ausreichend | bewundernswert |
beachtlich | blendend |
befriedigend | brillant |
erfreulich | einwandfrei |
fair | erstaunlich |
geeignet | erstklassig |
gefällig | fabelhaft |
günstig | glänzend |
passend | großartig |
recht | herrlich |
respektabel | hervorragend |
solide | köstlich |
perfekt | |
phänomenal | |
sensationell | |
tadellos | |
toll | |
überdurchschnittlich | |
vorbildlich | |
vorzüglich |
[ABAP] Dropdown list on selection screen
PARAMETER p_list TYPE c AS LISTBOX VISIBLE LENGTH 32. "Add OBLIGATORY to get rid of the empty line. Use DEFAULT to set the inital selection.
INITIALIZATION.
CALL FUNCTION 'VRM_SET_VALUES'
EXPORTING
id = 'P_LIST'
values = VALUE vrm_values( ( key = '1' text = 'Case 1' )
( key = '2' text = 'Case 2' )
( key = '3' text = 'Case 3' ) )
EXCEPTIONS
id_illegal_name = 1
OTHERS = 2.
AT SELECTION-SCREEN ON p_list.
DATA(dynprofields) = VALUE dynpread_tabtype( ( fieldname = 'P_LIST' ) ).
CALL FUNCTION 'DYNP_VALUES_READ'
EXPORTING
dyname = sy-cprog
dynumb = sy-dynnr
translate_to_upper = 'X'
TABLES
dynpfields = dynprofields. "find your selected value in column fieldvalue or directly in p_list
[ABAP] Activate and deactivate input fields via radiobuttons
*-----------------------------------------------------------------------
* SELEKTIONSBILD
*-----------------------------------------------------------------------
SELECTION-SCREEN BEGIN OF BLOCK b1 WITH FRAME TITLE text-001.
* Radiobutton 1 -> Deactivate Fields
SELECTION-SCREEN BEGIN OF LINE.
PARAMETERS: p_radio1 RADIOBUTTON GROUP rad1 DEFAULT 'X' USER-COMMAND rad.
SELECTION-SCREEN COMMENT 6(37) text-t01 FOR FIELD p_radio1.
SELECTION-SCREEN : END OF LINE.
* Radiobutton 2 -> Activate Fields
SELECTION-SCREEN : BEGIN OF LINE.
PARAMETERS: p_radio2 RADIOBUTTON GROUP rad1.
SELECTION-SCREEN COMMENT 6(37) text-t02 FOR FIELD p_radio2.
SELECTION-SCREEN : END OF LINE.
* Input fields
PARAMETERS:
p_vorna TYPE vorna OBLIGATORY DEFAULT 'Max',
p_nachn TYPE nachn OBLIGATORY DEFAULT 'Mustermann'.
SELECTION-SCREEN END OF BLOCK b1.
*----------------------------------------------------------------------
* AT SELECTION-SCREEN
*----------------------------------------------------------------------
AT SELECTION-SCREEN OUTPUT. " PBO
LOOP AT SCREEN.
CASE screen-name.
WHEN 'P_VORNA' OR 'P_NACHN'.
screen-input = COND #( WHEN p_radio2 = abap_true THEN 1 ELSE 0 ).
MODIFY SCREEN.
ENDCASE.
ENDLOOP.
[ABAP] JSON to ABAP with dereferencing
Recently I had to fetch an attachment from SuccessFactors. The API returns a huge JSON. Here only a few lines of that json.
{
"d": {
"__metadata": {
"uri": "https://apihostname.successfactors.com:443/odata/v2/Attachment(1000)",
"type": "SFOData.Attachment"
},
"attachmentId": "1000",
"fileName": "Testdokument.pdf",
"mimeType": "application/pdf",
"moduleCategory": "HRIS_ATTACHMENT",
"userId": "10000555",
"fileExtension": "pdf",
"fileContent": "JVBERi0xLjcKjp2jtMXW5/gKMiAwIG9iag0KWy9JQ0NCYXNlZCAzIDAgUl0NCmVuZG9iag0KMyAw\r\nIG9iag0KPDwNCi9GaWx0ZXIgL0ZsYXRlRGVjb2RlIA0KL0xlbmd0aCAyNTk2IA0KL04gMyANCj4+\r\nDQpzdHJlYW0NCnicnZZ3VFPZFofPvTe9UJIQipTQa2hSAkgNvUiRLioxCRBKwJAAIjZEVHBEUZGm\r\nCDIo4ICjQ5GxIoqFAVGx6wQZRNRxcBQblklkrRnfvHnvzZvfH/d+a5+9z91n733WugCQ/IMFwkxY\r\nCYAMoVgU4efFiI2LZ2AHAQzwAANsAOBws7NCFvhGApkCfNiMbJkT+Be9ug4g+fsq0z+MwQD/n5S5\r\nWSIxAFCYjOfy+NlcGRfJOD1XnCW3T8mYtjRNzjBKziJZgjJWk3PyLFt89pllDznzMoQ8GctzzuJl\r\n8OTcJ+ONORK+jJFgGRfnCPi5Mr4mY4N0SYZAxm/ksRl8TjYAKJLcLuZzU2RsLWOSKDKCLeN5AOB......"
...
}
}
Parsing the JSON to ABAP
SAP provides two classes /ui2/cl_json
and /ui2/cl_data_access
to work with JSONs and there are also many cool tools on https://dotabap.org/ for that.
Because it’s just a simple JSON I tried to avoid importing another class to the system. So I stayed with SAPs classes.
First deserialize the JSON with /ui2/cl_json
.
" Constants for properties
CONSTANTS gc_filecontent TYPE string VALUE 'FILECONTENT' ##NO_TEXT.
CONSTANTS gc_filename TYPE string VALUE 'FILENAME' ##NO_TEXT.
CONSTANTS gc_doc_cat TYPE string VALUE 'DOCUMENTCATEGORY' ##NO_TEXT.
DATA: lr_data TYPE REF TO data.
/ui2/cl_json=>deserialize( EXPORTING json = lv_responce "the repsonse contains the json string
CHANGING data = lr_data ).
I found three similiar ways to use the class /ui2/cl_data_access
to get the relevant data out of the JSON.
1. Using the class construktor and the value( )
method for earch property.
DATA: lv_filecontent_base64 TYPE string,
lv_filename TYPE string,
lv_documentcategory TYPE string.
/ui2/cl_data_access=>create( ir_data = lr_data iv_component = |D-{ gc_filecontent }| )->value( IMPORTING ev_data = lv_filecontent_base64 ).
/ui2/cl_data_access=>create( ir_data = lr_data iv_component = |D-{ gc_filename }| )->value( IMPORTING ev_data = lv_filename).
/ui2/cl_data_access=>create( ir_data = lr_data iv_component = |D-{ gc_doc_cat }| )->value( IMPORTING ev_data = lv_documentcategory ).
2. Create an instance as first step and pass the component. Reuse the instance with the value( )
method.
DATA: lv_filecontent_base64 TYPE string,
lv_filename TYPE string,
lv_documentcategory TYPE string.
DATA(lo_data_access) = /ui2/cl_data_access=>create( ir_data = lr_data
iv_component = |D-| ).
lo_data_access->at( |{ gc_filecontent }| )->value( IMPORTING ev_data = lv_filecontent_base64 ).
lo_data_access->at( |{ gc_filename }| )->value( IMPORTING ev_data = lv_filename ).
lo_data_access->at( |{ gc_doc_cat }| )->value( IMPORTING ev_data = lv_documentcategory ).
3. Use the ref( )
method to get a reference of a property value. Because it returns a generic data type (and you cannot dereference generic references) you have to use CAST
combined with dereferencing (->*
) to get the concret value.
DATA(lo_data_access) = /ui2/cl_data_access=>create( ir_data = lr_data
iv_component = |D-| ).
DATA(lv_filecontent_base64) = CAST string( lo_data_access->at( gc_filecontent )->ref( ) )->*.
DATA(lv_filename) = CAST string( lo_data_access->at( gc_filename )->ref( ) )->*.
DATA(lv_documentcategory) = CAST string( lo_data_access->at( gc_doc_cat )->ref( ) )->*.
In the end I stayed with version 3 because I prefere using inline declarations. The complete result looked like this:
" Constants for properties
CONSTANTS gc_filecontent TYPE string VALUE 'FILECONTENT' ##NO_TEXT.
CONSTANTS gc_filename TYPE string VALUE 'FILENAME' ##NO_TEXT.
CONSTANTS gc_doc_cat TYPE string VALUE 'DOCUMENTCATEGORY' ##NO_TEXT.
DATA: lr_data TYPE REF TO data.
/ui2/cl_json=>deserialize( EXPORTING json = lv_response "the repsonse contains the json string
CHANGING data = lr_data ).
DATA(lo_data_access) = /ui2/cl_data_access=>create( ir_data = lr_data
iv_component = |D-| ).
DATA(lv_filecontent_base64) = CAST string( lo_data_access->at( gc_filecontent )->ref( ) )->*.
DATA(lv_filename) = CAST string( lo_data_access->at( gc_filename )->ref( ) )->*.
DATA(lv_documentcategory) = CAST string( lo_data_access->at( gc_doc_cat )->ref( ) )->*.
" Decode BASE64 PDF to XString
DATA(lv_decodedx) = cl_http_utility=>if_http_utility~decode_x_base64( lv_filecontent_base64 ).
" XString to binary
DATA(lt_data) = cl_bcs_convert=>xstring_to_solix( lv_decodedx ).
" Download file
cl_gui_frontend_services=>gui_download( EXPORTING bin_filesize = xstrlen( lv_decodedx )
filename = lv_filename
filetype = 'BIN'
show_transfer_status = ' '
CHANGING data_tab = lt_data ).
When /ui2/cl_data_access
is not available (SAP_UI has to be at least 7.51, see note 2526405), you can do it the oldschool way.
" Constants for properties
CONSTANTS gc_filecontent TYPE string VALUE 'FILECONTENT' ##NO_TEXT.
CONSTANTS gc_filename TYPE string VALUE 'FILENAME' ##NO_TEXT.
CONSTANTS gc_doc_cat TYPE string VALUE 'DOCUMENTCATEGORY' ##NO_TEXT.
DATA: lr_data TYPE REF TO data.
/ui2/cl_json=>deserialize( EXPORTING json = lv_response "the repsonse contains the json string
CHANGING data = lr_data ).
ASSIGN lr_data->* TO FIELD-SYMBOL(<fs_d>).
ASSIGN COMPONENT 'D' OF STRUCTURE <fs_d> TO FIELD-SYMBOL(<fs_components>).
ASSIGN <fs_components>->* TO FIELD-SYMBOL(<fs_fields>).
ASSIGN COMPONENT gc_doc_cat OF STRUCTURE <fs_fields> TO FIELD-SYMBOL(<documentcategory>).
ASSIGN COMPONENT gc_filename OF STRUCTURE <fs_fields> TO FIELD-SYMBOL(<filename>).
ASSIGN COMPONENT gc_filecontent OF STRUCTURE <fs_fields> TO FIELD-SYMBOL(<filecontent>).
ASSIGN <documentcategory>->* TO FIELD-SYMBOL(<documentcategory_value>).
ASSIGN <filename>->* TO FIELD-SYMBOL(<filename_value>).
ASSIGN <filecontent>->* TO FIELD-SYMBOL(<filecontent_value>).
"...