主頁 > 移動端開發 > 如何使用C正確接收串行資料?

如何使用C正確接收串行資料?

2022-04-29 17:18:49 移動端開發

更新1: 短版:當串口設備發送時0x23 0x0 0x3b 0xa,我的程式可以讀取所有4個位元組(serial_getBiaststatus示例)。當串行設備將第二個位元組發送為0x3時,我的設備僅接收最后 2 個位元組(0x3b 0xa例如serial_getLedstatus

長版 我有一個串行設備,可以回答一些命令來設定和回傳一些選項的狀態,其中一個選項是 LED。要設定選項,我必須發送:

0xFF, 0x55, 0x<ADDR>, 0x<DATA>

(設備在 SET 命令后不回傳任何內容)

要閱讀此選項,我必須發送:

0xFF, 0xAA, 0x<ADDR>, 0xFF

設備將回傳:

0x23, 0x<VALUE>, 0x3B, 0x0A

除了這些選項,設備將不斷發送以換行結束的資料。所以我需要禁用這些資料,發送一個特殊的暫存器(地址 0x9)來禁用這個log資料,否則我將無法從 LED 或其他設備選項讀取狀態。

好的,我的問題是:當我將 LED 狀態設定為 3 (0x3) 時,我無法從設備讀取狀態!我的程式只從設備中讀取 2 個位元組,而不是 4 個位元組。如果我使用01值,則正確回傳狀態!(4位元組)。我確信設備正在發送正確的值(在這種情況下為 4 個位元組,0x23, 0x03, 0x3B, 0x0A因為我已經在 Windows 中使用 YAT 終端程式對其進行了測驗,并且這些值是正確的.....所以這不是設備問題,而是我的程式.

到目前為止,這是我的代碼。我正在將與串行設備的連接設定為非規范模式以設定/讀取設備選項(特別是因為“設定”不回傳任何內容,所以我無法讀取()并設定超時)......在設定選項之后,我將設備連接設定為規范模式并獲取必要的資料,直到程式結束。一切正常,除非我需要在設備選項中使用“3”......如果在設備上設定了選項本身(我可以直觀地驗證 LED),但是當我嘗試讀取這個 LED 值時,只有最后 2 個位元組回傳 ( 0x3b 0xa),而不是值(從 4 開始的第二個位元組)。


int serial_set_interface_attribs(int fd, int canonical) {    
    pthread_mutex_lock(&m_serial);    
    if (tcgetattr(fd, &tty) < 0) {
        printf("Error from tcgetattr: %s\n", strerror(errno));
        pthread_mutex_unlock(&m_serial);
        return -1;
    }


    switch (serial_speed) {

        case 57600:
            cfsetospeed(&tty, (speed_t) B57600);
            cfsetispeed(&tty, (speed_t) B57600);
            jonis_log_level(2, "Serial device speed set to 57600\n");
            break;

        case 115200:
            cfsetospeed(&tty, (speed_t) B115200);
            cfsetispeed(&tty, (speed_t) B115200);
            jonis_log_level(2, "Serial device speed set to 115200\n");
            break;

        case 230400:
            cfsetospeed(&tty, (speed_t) B230400);
            cfsetispeed(&tty, (speed_t) B230400);
            jonis_log_level(2, "Serial device speed set to 230400\n");
            break;

        case 460800:
            cfsetospeed(&tty, (speed_t) B460800);
            cfsetispeed(&tty, (speed_t) B460800);
            jonis_log_level(2, "Serial device speed set to 460800\n");
            break;

        case 500000:
            cfsetospeed(&tty, (speed_t) B500000);
            cfsetispeed(&tty, (speed_t) B500000);
            jonis_log_level(2, "Serial device speed set to 500000\n");
            break;

        case 576000:
            cfsetospeed(&tty, (speed_t) B576000);
            cfsetispeed(&tty, (speed_t) B576000);
            jonis_log_level(2, "Serial device speed set to 576000\n");
            break;

        case 921600:
            cfsetospeed(&tty, (speed_t) B921600);
            cfsetispeed(&tty, (speed_t) B921600);
            jonis_log_level(2, "Serial device speed set to 921600\n");
            break;


        default:
            cfsetospeed(&tty, (speed_t) B921600);
            cfsetispeed(&tty, (speed_t) B921600);
            jonis_log_level(2, "Serial device speed set to 921600\n");

    }


    tty.c_cflag |= CLOCAL | CREAD;
    tty.c_cflag &= ~CSIZE;
    tty.c_cflag |= CS8; /* 8-bit characters */
    tty.c_cflag &= ~PARENB; /* no parity bit */
    tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
    tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */

    if (canonical == 1) {
        jonis_log_level(1,"Interface in canonical mode\n");
        tty.c_lflag |= ICANON | ISIG; /* canonical input */
        tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);
    } else {
        jonis_log_level(1,"Interface in non-canonical mode\n");
        //Disable ECHO
        tty.c_lflag &= ~(ICANON);
        tty.c_lflag &= ~(ECHO | ECHOE);        
        tty.c_cc[VMIN] = 0;
        tty.c_cc[VTIME] = 10;

    }
    
    //tty.c_iflag &= ~IGNCR;  /* preserve carriage return - estava comentado */ 
    tty.c_iflag &= ~INPCK;
    tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
    tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no SW flowcontrol */

    tty.c_oflag &= ~OPOST;

    tty.c_cc[VEOL] = 0;
    tty.c_cc[VEOL2] = 0;
    tty.c_cc[VEOF] = 0x04;



    if (tcsetattr(fd, TCSANOW, &tty) != 0) {
        printf("Error from tcsetattr: %s\n", strerror(errno));        
        pthread_mutex_unlock(&m_serial);
        return -1;
    }    
    pthread_mutex_unlock(&m_serial);    
    return 0;
}

void *serial_threadGetSerialData(void *argv) {

    AN_NOTUSED(argv);
    // signal handlers:
    signal(SIGINT, jonisSigintHandler);
    signal(SIGTERM, jonisSigtermHandler);
    
    if (pthread_mutex_init(&m_serial, NULL) != 0) {
        printf("\n mutex init failed\n");
        exit(EXIT_FAILURE);
    }
        
    if (serial_device == NULL) {
        jonis_log("Can't start serial communication. Device is null.\n");
        return NULL;
    }


    fd_serial = open(serial_device, O_RDWR | O_NOCTTY | O_SYNC);
    if (fd_serial < 0) {
        jonis_log("Error opening %s: %s\n", serial_device, strerror(errno));
        return NULL;
    }    
    
    
    // Configue LED and other settings           
    struct sdongle_version *tmp = serial_getDongleVersion();
    if (tmp == NULL) {
        jonis_log_level(1, "Function to get dongle FW version returned NULL!\n");
    } else {        
        jonis_log("Serial dongle FW version: %d.%d\n",tmp->major,tmp->minor);
    }                    

    // Set LED to 3    
    serial_setLedstatus(3); 
    // Read LED status from device
    serial_getLedstatus();

    if (serial_bias_t == 1) {
        // Enable Bias T
        serial_setBiaststatus(1);
        printf("Definido biast como 1!\n");
    } else {
        // Disabl Bias-T
        serial_setBiaststatus(0);
        printf("Definido biast como 0!\n");
    }
    (...)
    
    serial_enableData();
            
    /* simple canonical input */
    do {


        char buf[150];
        //unsigned char *p;
        int rdlen;

        rdlen = read(fd_serial, buf, sizeof (buf) - 1);
        if (rdlen > 0) {
            buf[rdlen] = 0;
            //printf("Read (main) %d bytes: ", rdlen);
            /* first display as hex numbers then ASCII */
            //for (p = buf; rdlen-- > 0; p  ) {
            //    printf(" 0x%x", *p);
            //    if (*p < ' ')
            //        *p = '.';   /* replace any control chars */
            //}
            //printf("\n    \"%s\"\n\n", buf);
            //printf("%s", buf);

            // Proccess data
            //decodeRaw(buf);


        } else if (rdlen < 0) {
            jonis_log("Error from read: %d: %s\n", rdlen, strerror(errno));
        } else { /* rdlen == 0 */
            //printf("(main)Nothing read. EOF?\n");            
        }
        /* repeat read */
    } while (!MyProgram.exit);

    jonis_log_level(1,"Reseting Serial Dongle options.\n");    
    if (serial_setLedstatus(0) != 1) {
        jonis_log("Error reseting serial dongle LED status\n");
    }    
    
    if (fd_serial > -1) {
        close(fd_serial);
    }

    pthread_exit(EXIT_SUCCESS);

}

int serial_disableData(void) {

    if (fd_serial < 0) {
        jonis_log("Error disabling serial data: invalid serial connection.\n");
        return -1;
    }

    char disable_data[] = {0xFF, 0x55, 0x09, 0x01};

    serial_set_interface_attribs(fd_serial, 0);    
    jonis_log_level(1, "Canonical mode set to 0\n");    
    pthread_mutex_lock(&m_serial);
    
    int wlen = 0;

    wlen = write(fd_serial, disable_data, 4);
    if (wlen != 4) {
        jonis_log("Error from write: %d, %d\n", wlen, errno);
        pthread_mutex_unlock(&m_serial);
        return -1;
    }
    tcdrain(fd_serial); /* delay for output */
    
    usleep(100000);
    
    // Clear current buffer
    char buf[9000] = {0};
    int total_cleared = 0;

    int rdlen = 0;
    rdlen = read(fd_serial, buf, sizeof (buf) - 1);
    total_cleared = rdlen;
    jonis_log_level(1, "Clearing buffer. Current counter: %d. Returned: %d\n", total_cleared, rdlen);
    while (rdlen != 0) {
        rdlen = read(fd_serial, buf, sizeof (buf) - 1);
        total_cleared = total_cleared   rdlen;
        usleep(100000);
        jonis_log_level(1, "Clearing buffer. Current counter: %d. Returned: %d\n", total_cleared, rdlen);
    }

    jonis_log_level(1, "Finished sending 'disable_log' command do serial device! Data length in buffer: '%d'\n", total_cleared);
    pthread_mutex_unlock(&m_serial);
    return 1;

}

int serial_enableData(void) {

    if (fd_serial < 0) {
        jonis_log("Error enabling serial data: invalid serial connection.\n");
        return -1;
    }

    serial_set_interface_attribs(fd_serial, 1);
    pthread_mutex_lock(&m_serial);
    char disable_data[] = {0xFF, 0x55, 0x09, 0x00};

    int wlen = 0;

    wlen = write(fd_serial, disable_data, 4);
    if (wlen != 4) {
        jonis_log("Error from write: %d, %d\n", wlen, errno);
        pthread_mutex_unlock(&m_serial);
        return -1;
    }
    tcdrain(fd_serial); /* delay for output */

    jonis_log_level(1, "Finished sending 'enable_log' command do serial device!\n");

    pthread_mutex_unlock(&m_serial);
    return 1;

}

struct sdongle_version *serial_getDongleVersion(void) {

    if (fd_serial < 0) {
        jonis_log("Error getting serial data: invalid serial connection.\n");
        return NULL;
    }

    if (serial_disableData() < 0) {
        jonis_log("Could not disable data\n");
        return NULL;
    }

    char disable_data[] = {0xFF, 0xAA, 0x0F, 0xFF};
    int wlen = 0;

    wlen = write(fd_serial, disable_data, 4);
    if (wlen != 4) {
        jonis_log("Error from write: %d, %d\n", wlen, errno);
        return NULL;
    }
    tcdrain(fd_serial); /* delay for output */
    usleep(100000);

    char buf[150];
    char *p;
    int rdlen;

    //rdlen = read(fd_serial, buf, sizeof (buf) - 1);
    //if (rdlen > 0) {
    while ((rdlen = read(fd_serial, buf, sizeof (buf) - 1)) < 4 || !Modes.exit) {    
        buf[rdlen] = 0;
        //printf("(Version) Read '%d' bytes: ", rdlen);
        if (rdlen == 4 && buf[0] == 0x23 && buf[2] == 0x3b && buf[3] == 0xa) {
            jonis_log_level(1, "Version string found!\n");
            int minor = buf[1] << 2 >> 2;
            int major = buf[1] >> 6;
            jonis_log_level(1, "Minor version: %d, Major version: %d\n", minor, major);

            struct sdongle_version *ver = malloc(sizeof (struct sdongle_version));
            ver->major = major;
            ver->minor = minor;
            return ver;
        }

        /* first display as hex numbers then ASCII */
        for (p = buf; rdlen-- > 0; p  ) {
            //printf(" 0x%x", *p);            
        }
        //printf("\n    (version)Value: \"%s\"\n\n", buf);


    }

    return NULL;

}


int serial_getLedstatus(void) {

    if (fd_serial < 0) {
        jonis_log("Error getting serial data: invalid serial connection.\n");
        return -1;
    }

    if (serial_disableData() < 0) {
        jonis_log("Could not disable data\n");
        return -1;
    }

    char led_status_data[] = {0xFF, 0xAA, 0x8, 0xFF};

    int wlen = 0;

    wlen = write(fd_serial, led_status_data, 4);
    if (wlen != 4) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd_serial); /* delay for output */
    sleep(1);

    char buf[150] = {0};
    char *p = NULL;
    int rdlen = 0;
    int tries = 0;
    
    while (((rdlen = read(fd_serial, buf, sizeof (buf) - 1)) < 4 && !Modes.exit) && tries <= 5) {
        jonis_log_level(1,"(led) Read '%d' bytes: \n", rdlen);
        tries  ;
        // Force rwrite command
        wlen = write(fd_serial, led_status_data, 4);
        tcdrain(fd_serial);
        sleep(1);        
        buf[rdlen] = 0;                
        /* first display as hex numbers then ASCII */
        for (p = buf; rdlen-- > 0; p  ) {
            if (debug_level >= 1) { 
                printf(" 0x%x", *p); 
            }
        }
        if (debug_level >= 1) { 
            printf("\n");
            jonis_log_level(1,"    (led)Value: \"%s\"\n\n", buf);
        }
    } 
    
    if (rdlen > 0) {
        jonis_log_level(1,"Debug -> Received chars in LED Status\n");
        jonis_log_level(1,"(led) Read '%d' bytes: ", rdlen);        
        buf[rdlen] = 0;                
        /* first display as hex numbers then ASCII */
        for (p = buf; rdlen-- > 0; p  ) {
            if (debug_level >= 1) { 
                printf(" 0x%x", *p);            
            }
        }
        if (debug_level >= 1) { 
            printf("\n");
            jonis_log_level(1,"    (led)Value: \"%s\"\n\n", buf);
        }
    }
    
    jonis_log_level(1,"LED Status (function): %d\n",buf[1]);
    return buf[1];

}


int serial_setLedstatus(char led_status) {

    
    if (fd_serial < 0) {
        jonis_log("Error getting serial data: invalid serial connection.\n");
        return -1;
    }

    if (serial_disableData() < 0) {
        jonis_log("Could not disable data\n");
        return -1;
    }    
    
    char led_data[] = {0xFF, 0x55, 0x08, led_status};
    int wlen = 0;
    wlen = write(fd_serial, led_data, 4);
    if (wlen != 4) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd_serial); /* delay for output */
    //serial_getLedstatus();
    return 1;
}

int serial_getBiaststatus(void) {

    if (fd_serial < 0) {
        jonis_log("Error getting serial data: invalid serial connection.\n");
        return -1;
    }

    if (serial_disableData() < 0) {
        jonis_log("Could not disable data\n");
        return -1;
    }

    char bias_status_data[] = {0xFF, 0xAA, 0x07, 0xFF};

    int wlen = 0;

    wlen = write(fd_serial, bias_status_data, 4);
    if (wlen != 4) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd_serial); /* delay for output */
    usleep(100000);

    char buf[150];
    char *p;
    int rdlen;

    rdlen = read(fd_serial, buf, sizeof (buf) - 1);
    if (rdlen > 0) {
        buf[rdlen] = 0;
        printf("(biast) Read '%d' bytes: ", rdlen);
        
        /* first display as hex numbers then ASCII */
        for (p = buf; rdlen-- > 0; p  ) {
            printf(" 0x%x", *p);            
        }
        printf("\n    (biast)Value: \"%s\"\n\n", buf);


    } else if (rdlen < 0) {
        jonis_log("Error from read: %d: %s\n", rdlen, strerror(errno));
    } else { /* rdlen == 0 */
        //printf("(led)Nothing read. EOF?\n");        
    }    
    jonis_log_level(1,"BIAS-T Status (function): %d\n",buf[1]);
    return buf[1];

}


int serial_setBiaststatus(char biast_status) {

    if (fd_serial < 0) {
        jonis_log("Error getting serial data: invalid serial connection.\n");
        return -1;
    }

    if (serial_disableData() < 0) {
        jonis_log("Could not disable data\n");
        return -1;
    }

    char biast_data[] = {0xFF, 0x55, 0x07, biast_status};
    int wlen = 0;
    wlen = write(fd_serial, biast_data, 4);
    if (wlen != 4) {
        printf("Error from write: %d, %d\n", wlen, errno);
    }
    tcdrain(fd_serial); /* delay for output */
    usleep(100000);
    
    if (serial_getBiaststatus() == biast_status) {    
        return 1;
    } else {
        return 0;
    }

}

這是回傳的文本(注意僅從 LED 狀態接收到 2 個位元組):

[2022-04-28 09:22:00] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:00] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:00] [serial_disableData]  Clearing buffer. Current counter: 1. Returned: 1
[2022-04-28 09:22:01] [serial_disableData]  Clearing buffer. Current counter: 1. Returned: 0
[2022-04-28 09:22:01] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '1'
[2022-04-28 09:22:01] [serial_getDongleVersion]  Version string found!
[2022-04-28 09:22:01] [serial_getDongleVersion]  Minor version: 34, Major version: 0
[2022-04-28 09:22:01]  Serial dongle FW version: 0.34
[2022-04-28 09:22:01] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:01] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:02] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:02] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
[2022-04-28 09:22:02] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:02] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:03] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:03] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
[2022-04-28 09:22:04] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:05] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:05] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:06] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:06] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:07] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:07] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:08] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:08] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:09] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:09] [serial_getLedstatus]  (led) Read '2' bytes:
 0x3b 0xa
[2022-04-28 09:22:10] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:10] [serial_getLedstatus]  Debug -> Received chars in LED Status
[2022-04-28 09:22:10] [serial_getLedstatus]  (led) Read '2' bytes:  0x3b 0xa
[2022-04-28 09:22:10] [serial_getLedstatus]      (led)Value: ";
"

[2022-04-28 09:22:10] [serial_getLedstatus]  LED Status (function): 10
[2022-04-28 09:22:10] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:10] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:11] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:11] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
[2022-04-28 09:22:12] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:12] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:13] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:13] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
[2022-04-28 09:22:13] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:13] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:14] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:14] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
[2022-04-28 09:22:14] [serial_set_interface_attribs]  Interface in non-canonical mode
[2022-04-28 09:22:14] [serial_disableData]  Canonical mode set to 0
[2022-04-28 09:22:15] [serial_disableData]  Clearing buffer. Current counter: 0. Returned: 0
[2022-04-28 09:22:15] [serial_disableData]  Finished sending 'disable_log' command do serial device! Data length in buffer: '0'
(biast) Read '4' bytes:  0x23 0x0 0x3b 0xa
    (biast)Value: "#"

[2022-04-28 09:22:15] [serial_getBiaststatus]  BIAS-T Status (function): 0
[2022-04-28 09:22:15] [serial_set_interface_attribs]  Interface in canonical mode
[2022-04-28 09:22:15] [serial_enableData]  Finished sending 'enable_log' command do serial device!


再次:設備回傳正確的位元組數(4),即使選項 os 的值為 3,但我的程式無法準備好所有這些位元組,只有最后 2 個。我在這里缺少什么?謝!

uj5u.com熱心網友回復:

好的,我的問題是:當我將 LED 狀態設定為 3 (0x3) 時,我無法從設備讀取狀態!
...
我確信設備正在發送正確的值(4個位元組,在這種情況下,0x23, 0x03, 0x3B, 0x0A...

0x03也是名為 ETX 的 ASCII 控制代碼。

termios 特殊字符VINTR默認值為 ,0x03也稱為 ETX 和 Ctrl-C。
當 c_lflag 的 termios ISIG 屬性設定時,接收VINTR字符將導致行程獲得 SIGINT 信號,并且從輸入緩沖區中洗掉該字符。


if (canonical == 1) {
    ...
    tty.c_lflag |= ICANON | ISIG; /* canonical input */
    ...
} else {
    ...
    tty.c_lflag &= ~(ICANON);
    tty.c_lflag &= ~(ECHO | ECHOE);        
    ...
}

您的程式將 ISIG 屬性設定為“規范”模式,否則保持 c_lflag 中的該屬性不變。
顯然VINTR仍然有它的默認值0x03

最終效果是始終啟用 ISIG 屬性,因此接收 0x03將始終不可讀。

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/467409.html

標籤:C linux 串行端口 术语表

上一篇:Flex和Bison$variables給出了意想不到的值

下一篇:HAL_UART_Transmit_IT如何在STM32F091VB上管理串行發送資料

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【從零開始擼一個App】Dagger2

    Dagger2是一個IOC框架,一般用于Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架代碼碎片化,注解滿天飛的傳統。嘗試將各處代碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 與Spring不同的是,Spring是通過反射 ......

    uj5u.com 2020-09-10 06:57:59 more
  • Flutter Weekly Issue 66

    新聞 Flutter 季度調研結果分享 教程 Flutter+FaaS一體化任務編排的思考與設計 詳解Dart中如何通過注解生成代碼 GitHub 用對了嗎?Flutter 團隊分享如何管理大型開源專案 插件 flutter-bubble-tab-indicator A Flutter librar ......

    uj5u.com 2020-09-10 06:58:52 more
  • Proguard 常用規則

    介紹 Proguard 入口,如何查看輸出,如何使用 keep 設定入口以及使用實體,如何配置壓縮,混淆,校驗等規則。

    ......

    uj5u.com 2020-09-10 06:59:00 more
  • Android 開發技術周報 Issue#292

    新聞 Android即將獲得類AirDrop功能:可向附近設備快速分享檔案 谷歌為安卓檔案管理應用引入可安全隱藏資料的Safe Folder功能 Android TV新主界面將顯示電影、電視節目和應用推薦內容 泄露的Android檔案暗示了傳說中的谷歌Pixel 5a與折疊屏新機 谷歌發布Andro ......

    uj5u.com 2020-09-10 07:00:37 more
  • AutoFitTextureView Error inflating class

    報錯: Binary XML file line #0: Binary XML file line #0: Error inflating class xxx.AutoFitTextureView 解決: <com.example.testy2.AutoFitTextureView android: ......

    uj5u.com 2020-09-10 07:00:41 more
  • 根據Uri,Cursor沒有獲取到對應的屬性

    Android: 背景:呼叫攝像頭,拍攝視頻,指定保存的地址,但是回傳的Cursor檔案,只有名稱和大小的屬性,沒有其他諸如時長,連ID屬性都沒有 使用 cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DURATIO ......

    uj5u.com 2020-09-10 07:00:44 more
  • Android連載29-持久化技術

    一、持久化技術 我們平時所使用的APP產生的資料,在記憶體中都是瞬時的,會隨著斷電、關機等丟失資料,因此android系統采用了持久化技術,用于存盤這些“瞬時”資料 持久化技術包括:檔案存盤、SharedPreference存盤以及資料庫存盤,還有更復雜的SD卡記憶體儲。 二、檔案存盤 最基本存盤方式, ......

    uj5u.com 2020-09-10 07:00:47 more
  • Android Camera2Video整合到自己專案里

    背景: Android專案里呼叫攝像頭拍攝視頻,原本使用的 MediaStore.ACTION_VIDEO_CAPTURE, 后來因專案需要,改成了camera2 1.Camera2Video 官方demo有點問題,下載后,不能直接整合到專案 問題1.多次拍攝視頻崩潰 問題2.雙擊record按鈕, ......

    uj5u.com 2020-09-10 07:00:50 more
  • Android 開發技術周報 Issue#293

    新聞 谷歌為Android TV開發者提供多種新功能 Android 11將自動填表功能整合到鍵盤輸入建議中 谷歌宣布Android Auto即將支持更多的導航和數字停車應用 谷歌Pixel 5只有XL版本 搭載驍龍765G且將比Pixel 4更便宜 [圖]Wear OS將迎來重磅更新:應用啟動時間 ......

    uj5u.com 2020-09-10 07:01:38 more
  • 海豚星空掃碼投屏 Android 接收端 SDK 集成 六步驟

    掃碼投屏,開放網路,獨占設備,不需要額外下載軟體,微信掃碼,發現設備。支持標準DLNA協議,支持倍速播放。視頻,音頻,圖片投屏。好點意思。還支持自定義基于 DLNA 擴展的操作動作。好像要收費,沒體驗。 這里簡單記錄一下集成程序。 一 跟目錄的build.gradle添加私有mevan倉庫 mave ......

    uj5u.com 2020-09-10 07:01:43 more
最新发布
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:40:31 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:40:11 more
  • 歡迎頁輪播影片

    如圖,引導開始,球從上落下,同時淡入文字,然后文字開始輪播,最后一頁時停止,點擊進入首頁。 在來看看效果圖。 重力球先不講,主要歡迎輪播簡單實作 首先新建一個類 TextTranslationXGuideView,用于影片展示 文本是類似的,最后會有個圖片箭頭影片,布局很簡單,就是一個 TextVi ......

    uj5u.com 2023-04-20 08:39:36 more
  • 【FAQ】關于華為推送服務因營銷訊息頻次管控導致服務通訊類訊息

    一. 問題描述 使用華為推送服務下發IM訊息時,下發訊息請求成功且code碼為80000000,但是手機總是收不到訊息; 在華為推送自助分析(Beta)平臺查看發現,訊息發送觸發了頻控。 二. 問題原因及背景 2023年1月05日起,華為推送服務對咨詢營銷類訊息做了單個設備每日推送數量上限管理,具體 ......

    uj5u.com 2023-04-20 08:39:13 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:16:23 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:16:15 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:15:46 more
  • iOS從UI記憶體地址到讀取成員變數(oc/swift)

    開發除錯時,我們發現bug時常首先是從UI顯示發現例外,下一步才會去定位UI相關連的資料的。XCode有給我們提供一系列debug工具,但是很多人可能還沒有形成一套穩定的除錯流程,因此本文嘗試解決這個問題,順便提出一個暴論:UI顯示例外問題只需要兩個步驟就能完成定位作業的80%: 定位例外 UI 組 ......

    uj5u.com 2023-04-19 09:14:53 more
  • FIDE重磅更新!性能飛躍!體驗有禮!

    FIDE 開發者工具重構升級啦!實作500%性能提升,誠邀體驗! 一直以來不少開發者朋友在社區反饋,在使用 FIDE 工具的程序中,時常會遇到諸如加載不及時、代碼預覽/渲染性能不如意的情況,十分影響開發體驗。 作為技術團隊,我們深知一件趁手的開發工具對開發者的重要性,因此,在2023年開年,FinC ......

    uj5u.com 2023-04-19 09:14:08 more
  • 游戲內嵌社區服務開放,助力開發者提升玩家互動與留存

    華為 HMS Core 游戲內嵌社區服務提供快速訪問華為游戲中心論壇能力,支持玩家直接在游戲內瀏覽帖子和交流互動,助力開發者擴展內容生產和觸達的場景。 一、為什么要游戲內嵌社區? 二、游戲內嵌社區的典型使用場景 1、游戲內打開論壇 您可以在游戲內繪制論壇入口,為玩家提供沉浸式發帖、瀏覽、點贊、回帖、 ......

    uj5u.com 2023-04-19 09:08:34 more