ImageVerifierCode 换一换
格式:DOC , 页数:36 ,大小:427KB ,
资源ID:12006646      下载积分:10 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/12006646.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(Android原生C开发.doc)为本站上传会员【仙人****88】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

Android原生C开发.doc

1、Android原生(Native)C开发之一:环境搭建篇 (转)(2009-08-28 16:53:24) 标签:it  原文: Android是基于Linux的操作系统,处理器是ARM的,所以要在Linux或Windows等x86系统上编译Android能运行的程序,你需要一个交叉编译器。 在Linux下面,你可以自已编译一个交叉编译环境,但Windows下面,就比较复杂(也可以在cygwin中编译一个),但你可以选择下载一个现成的交叉编译环境: Windows: Linux: 安装好了之后,将 CodeSourcery编译器的bin目录 (我的是D:\Progr

2、am Files\CodeSourcery\Sourcery G++ Lite\bin)加入你的PATH环境变量中,就可以开始你的Android Native C开发之旅了,写好一个简单的C程序: #include int main(int argc, char** argv) {  printf("hello android!\nI'm %s!\nI like android very much!!!\n", "Martin Foo");    return 0; } 另存成hello.c,进入命令行模式,确保交叉编译器的bin目录,及Android

3、SDK的tools目录在你的系统环境变量的path里面,用如下命令编译: arm-none-linux-gnueabi-gcc -static hello.c -o hello 注意,一定要加上static参数,否则编译好的可能会在Android上不能运行。 启动Android模拟器,用如下命令将文件push到Android模拟器上: adb shell mkdir /dev/sample adb push hello /dev/sample/hello adb shell chmod 777 /dev/sample/hello 先创建 /dev/sample目录,再将编译好的h

4、ello上传上去,最后将hello改成可执行的。 再进入命令行模式,进入Android的shell环境: adb shell #cd /dev/sample #./hello 进入 /dev/sample目录,执行hello,运行结果如下图: Android原生(Native)C开发之二:framebuffer篇 (转)(2009-08-28 16:54:02) 标签:it   原文: 如对Android原生(Natvie)C开发还任何疑问,请参阅《Android原生(Native)C开发之一:环境搭建篇》: 虽然现在能通过交叉环境编译程序,并push到And

5、roid上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的 framebuffer 技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。 操作framebuffer的主要步骤如下: 1、打开一个可用的FrameBuffer设备; 2、通过mmap调用把显卡的物理内存空间映射到用户空间; 3、更改内存空间里的像素数据并显示; 4、退出时关闭framebuffer设备。 下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下: #incl

6、ude #include #include #include #include inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b) {     return (  (((r >> 3) & 31) << 11) |  (((g >> 2) & 63) << 5)  |   ((b >> 3) & 31)        );

7、 } int main() {     int fbfd = 0;     struct fb_var_screeninfo vinfo;     struct fb_fix_screeninfo finfo;     long int screensize = 0;  char *fbp = 0;     int x = 0, y = 0;     int guage_height = 20, step = 10;     long int location = 0;     // Open the file for reading and writing     fb

8、fd = open("/dev/graphics/fb0", O_RDWR);     if (!fbfd) {         printf("Error: cannot open framebuffer device.\n");         exit(1);     }     printf("The framebuffer device was opened successfully.\n");     // Get fixed screen information     if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {

9、         printf("Error reading fixed information.\n");         exit(2);     }     // Get variable screen information     if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {         printf("Error reading variable information.\n");         exit(3);     }  printf("sizeof(unsigned short) = %d\n", si

10、zeof(unsigned short));     printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );  printf("xoffset:%d, yoffset:%d, line_length: %d\n", vinfo.xoffset, vinfo.yoffset, finfo.line_length );     // Figure out the size of the screen in bytes     screensize = vinfo.xres * vinfo.yres *

11、 vinfo.bits_per_pixel / 8;;     // Map the device to memory     fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,                        fbfd, 0);     if ((int)fbp == -1) {         printf("Error: failed to map framebuffer device to memory.\n");         exit(4);     }    

12、printf("The framebuffer device was mapped to memory successfully.\n");  //set to black color first  memset(fbp, 0, screensize);     //draw rectangle     y = (vinfo.yres - guage_height) / 2 - 2;       // Where we are going to put the pixel     for (x = step - 2; x < vinfo.xres - step + 2; x++) {

13、         location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                        (y+vinfo.yoffset) * finfo.line_length;         *((unsigned short int*)(fbp + location)) = 255;     }     y = (vinfo.yres + guage_height) / 2 + 2;       // Where we are going to put the pixel     for (x =

14、step - 2; x < vinfo.xres - step + 2; x++) {         location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                        (y+vinfo.yoffset) * finfo.line_length;         *((unsigned short int*)(fbp + location)) = 255;     }     x = step - 2;     for (y = (vinfo.yres - guage_height) /

15、 2 - 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {         location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                        (y+vinfo.yoffset) * finfo.line_length;         *((unsigned short int*)(fbp + location)) = 255;     }     x = vinfo.xres - step + 2;     for (y = (vin

16、fo.yres - guage_height) / 2 - 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {         location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                        (y+vinfo.yoffset) * finfo.line_length;         *((unsigned short int*)(fbp + location)) = 255;     }     // Figure out where

17、in memory to put the pixel     for ( x = step; x < vinfo.xres - step; x++ ) {         for ( y = (vinfo.yres - guage_height) / 2; y < (vinfo.yres + guage_height) / 2; y++ ) {             location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                        (y+vinfo.yoffset) * finfo.lin

18、e_length;             if ( vinfo.bits_per_pixel == 32 ) {                 *(fbp + location) = 100;        // Some blue                 *(fbp + location + 1) = 15+(x-100)/2;     // A little green                 *(fbp + location + 2) = 200-(y-100)/5;    // A lot of red                 *(fbp + lo

19、cation + 3) = 0;      // No transparency             } else { //assume 16bpp                 unsigned char b = 255 * x / (vinfo.xres - step);                 unsigned char g = 255;     // (x - 100)/6 A little green                 unsigned char r = 255;    // A lot of red                 unsign

20、ed short int t = make16color(r, g, b);                 *((unsigned short int*)(fbp + location)) = t;             }         }   //printf("x = %d, temp = %d\n", x, temp);         //sleep to see it         usleep(200);     }     //clean framebuffer     munmap(fbp, screensize);     close(fbfd)

21、     return 0; } 注意,在Android环境,framebuffer设备不是象linux一样的 /dev/fb0,而是 /dev/graphics/fb0 , fbfd = open("/dev/graphics/fb0", O_RDWR); 打开framebuffer设备,     fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,                        fbfd, 0); 将设备map到一块内存,然后就可以操作这块内存空间来显示你想画的图形了。

22、 最后别忘了关闭设备:     munmap(fbp, screensize);     close(fbfd); 效果图如下: Android原生(Native)C开发之三:鼠标事件篇(捕鼠记)(2009-08-28 16:55:10) 标签:it   原文: 在做SDL至Android的移植时,键盘事件是能正常捕获到,看了SLD的源码,发现用的device是 /dev/tty0,但是鼠标叫是不能成功捕获,总是得到 0,运行命令查看devices时,显示如下:  # cat /proc/bus/input/devices cat /proc/bus/i

23、nput/devices I: Bus=0000 Vendor=0000 Product=0000 Version=0000 N: Name="qwerty" P: Phys= S: Sysfs=/class/input/input0 U: Uniq= H: Handlers=kbd mouse0 event0 B: EV=2f B: KEY=ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff ffffffff f fffffff ffffffff ffffffff ffffffff ffffffff

24、ffffffff ffffffff fffffffe B: REL=3 B: ABS=7 B: SW=1 进入 /dev/input 目录,发现在3个device文件:mice,mouse0,event0,分别 cat这3个文件,发现只有 event0 有反应,如下图: 而且不管是点击鼠标还是按键,都有反应,但显示的是一堆乱码,而且点击鼠标出来的东西要多一点,难道这就是传说是的 touchscreen ?! 为了分析 event0 的返回值,写了一段代码 testmice.c,如下:  #include #include #inc

25、lude #include static int event0_fd = -1; struct input_event ev0[64]; //for handling event0, mouse/key/ts static int handle_event0() {     int button = 0, realx = 0, realy = 0, i, rd;     rd = read(event0_fd, ev0, sizeof(struct input_event) * 64);     if ( rd < sizeo

26、f(struct input_event) ) return 0;     for (i = 0; i < rd / sizeof(struct input_event); i++) {         printf("", ev0[i].type, ev0[i].code, ev0[i].value);         if (ev0[i].type == 3 && ev0[i].code == 0)             realx = ev0[i].value;         else if (ev0[i].type == 3 && ev0[i].code == 1)  

27、           realy = ev0[i].value;         else if (ev0[i].type == 1) {             if (ev0[i].code == 158) {                 //if key esc then exit                 return 0;             }         } else if (ev0[i].type == 0 && ev0[i].code == 0 && ev0[i].value == 0) {             realx = 0, rea

28、ly = 0;         }         printf("event(%d): type: %d; code: %3d; value: %3d; realx: %3d; realy: %3d\n", i,    ev0[i].type, ev0[i].code, ev0[i].value, realx, realy);     }     return 1; } int main(void) {  int done = 1;     printf("sizeof(struct input_event) = %d\n", sizeof(struct input_eve

29、nt));     event0_fd = open("/dev/input/event0", O_RDWR);     if ( event0_fd < 0 )         return -1;     while ( done ) {   printf("begin handel_event0...\n");         done = handle_event0();   printf("end handel_event0...\n");     }     if ( event0_fd > 0 ) {         close(event0_fd);   

30、      event0_fd = -1;     }     return 0; } 用交叉编译器编译好后(编译过程就不再详述,请参见 blog:Android原生(Native)C开发之一:环境搭建篇),push至 emulator后执行后,切换到android 模拟器,在模拟器上点几下mouse,程序就会打出你点击的信息,效果如下,果然能正确得到点击的 mouse pos,如下图: 分析上面的返回值,发现当按下 mouse left button 时,会得到4个事件,2个 type = 3 的事件返回了 pos x, pos y 的值,即mouse click pos, 另

31、外1个 type = 1 的事件是按键事件(keydown),value就是按下的键的key,为0的应该就是 key的release事件,当松开 mouse时,也会得到两个 type = 1, 0 的事件,没有仔细去看它们的返回值,反正已经正确得到了 mosue的事件,下一步就是改SDL的事件驱动源码了... Android原生(Native)C开发之四:SDL移植笔记  (转)(2009-08-28 16:56:38) 标签:it   原文: SDL(Simple DirectMedia Layer)是一套开放源码的跨平台多媒体开发库,使用C语言写成。SDL提供了多种图像、

32、声音、键盘等的实现,可配置性与移植性非常高,开发者可以开发出跨多个平台(Linux、Windows、Mac OS X、Symbian、Widnows Mobiel等嵌入式系统,当然也包括今天要移植的平台:Android)的应用,目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用。 目前,SDL的稳定版本是 1.2.13,1.3还在开发中,可以通过SVN得到最新的代码,本次移植以 1.2.13为准,没有测试 1.3版的源码。请从 SDL 的官方网站下载 1.2.13 的源码,文件名为:SDL-1.2.13.zip,并解压,将得到一个 SDL-1.2.13 目录。 在Native编译SD

33、L之前,要先装 Code Sourcery公司的arm交叉编译器,如果是用Windows操作系统,则一定要装 Cygwin(一个在windows上模拟linux的软件),因为在编译时要用到一些 linux命令,具体的步骤请参见:Port SDL/TinySDGL to android with native C,或自已在网上搜一些资料。 因为SDL是用纯C写的一套类库,所以移植性非常好,官方支持的系统有:Linux, Windows, Windows CE, BeOS, MacOS, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, I

34、RIX, and QNX,非官方支持的有:AmigaOS, Dreamcast, Atari, AIX, OSF/Tru64, RISC OS, SymbianOS, and OS/2,而且网上也有人将SDL移植到很多其他嵌入式系统,甚至有人将SDL移植到 Moto A1200,如此强大的可移植性,其架构真是值得好好学习。 现在切入正题,如何为Android量身定做一个 SDL,下面就从视频,音频,输入事件,定时器(video,audio,events[key,mouse],timer),多线程等几个方面来分析: 1.首先讲视频方面,Android是一个定制的Linux操作系统,Linux

35、显示要么用 X11,要么用framebuffer技术,很显然Android并没有集成 X11(也许Android的软件界面是基于X11的?!),那只有唯一的选择:framebuffer! 打开$SDL/src/video目录,可以发现SDL支持多达30多种的视频显示技术,其中包括我们想要的fbcon及directfb,directfb我没有做测试,也许显示效果会比linux自带的fbcon好,有兴趣的朋友可以试一下,成功了别忘了告诉我; 2.再来谈音频,记得一个广告词:没有声音,再好的戏也出不来!可见音频对多媒体应用的重要性。 这次用的是OSS的driver,但用的是dsp及dma的实现

36、但在打开Android指定的音频文件 /dev/eac 时有误,所以音频这一块只是能编译通过,不能正常运行,正在考虑用ALSA (Advanced Linux Sound Architecture) 替代; 关于OSS大家可以参看IBM的文章: OSS--跨平台的音频接口简介,写得比较详细。 3.输入事件(键盘,鼠标)中的键盘事件不需要任何更改,就能正常处理,用的设备文件是 /dev/tty0, 但鼠标事件却不能正常处理,加上DEBUG_MOUSE发现用的是PS2的鼠标,但其实Android用的不是PS2的鼠标,用的应该是触摸屏(TouchScreen)鼠标,设备文件是 /dev/in

37、put/event0,详情请参见本人的blog: Android原生(Native)C开发之三:鼠标事件篇(捕鼠记),经过改动后,基本能实现鼠标的处理; 4.定时器用的是unix的实现; 5.多线程用的是pthread的实现,unix系统都是用pthread来实现多线程的,在 ln demo时别忘了加 -lpthread; 6.加载动态库用的是unix 的 dl库,同样,在ln demo时别忘了加 -ldl。 SDL提供了一个最小化的Makefile:Makefile.minimal,所有的实现都是 dummy,就是一个空的实现,编译能通过,但运行时什么都不能做,根据上面的分析,将 M

38、akefile.minimal 的内容改成如下:  # Makefile to build the SDL library INCLUDE = -I./include CFLAGS  = -g -s -O2 $(INCLUDE) CC  = arm-none-linux-gnueabi-gcc AR  = arm-none-linux-gnueabi-ar RANLIB = arm-none-linux-gnueabi-ranlib CONFIG_H = include/SDL_config.h TARGET  = libSDL.a SOURCES = \  src/*.c

39、 \  src/audio/*.c \  src/cdrom/*.c \  src/cpuinfo/*.c \  src/events/*.c \  src/file/*.c \  src/joystick/*.c \  src/stdlib/*.c \  src/thread/*.c \  src/timer/*.c \  src/video/*.c \  src/audio/dsp/*.c \  src/audio/dma/*.c \  src/video/fbcon/*.c \  src/joystick/dummy/*.c \  src/cdrom/dum

40、my/*.c \  src/thread/pthread/*.c \  src/timer/unix/*.c \  src/loadso/dlopen/*.c \ OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g') all: $(TARGET) $(TARGET): $(CONFIG_H) $(OBJECTS)  $(AR) crv $@ $^  $(RANLIB) $@ $(CONFIG_H):  cp $(CONFIG_H).default $(CONFIG_H) clean:  rm -f $(TAR

41、GET) $(OBJECTS) 最后将$SDL\include\SDL_config_minimal.h的内容改成如下: #ifndef _SDL_config_minimal_h #define _SDL_config_minimal_h #include "SDL_platform.h" #include typedef signed char int8_t; typedef unsigned char uint8_t; typedef signed short int16_t; typedef unsigned short uint16_t; t

42、ypedef signed int int32_t; typedef unsigned int uint32_t; typedef unsigned int size_t; //typedef unsigned long uintptr_t; #define HAVE_LIBC 1 #ifdef  HAVE_LIBC    #define HAVE_ALLOCA_H  1  #define HAVE_SYS_TYPES_H 1  #define HAVE_STDIO_H  1  #define STDC_HEADERS  1  #define HAVE_STDLIB_H 

43、 1  #define HAVE_STDARG_H  1  #define HAVE_MALLOC_H  1  #define HAVE_MEMORY_H  1  //#define HAVE_STRING_H   1  //#define HAVE_STRINGS_H  1  #define HAVE_INTTYPES_H  1  #define HAVE_STDINT_H  1  #define HAVE_CTYPE_H  1  #define HAVE_MATH_H   1  //#define HAVE_ICONV_H   1  #define HAVE_SIGN

44、AL_H  1  #define HAVE_ALTIVEC_H  1    #define HAVE_MALLOC   1  #define HAVE_CALLOC   1  #define HAVE_REALLOC  1  #define HAVE_FREE   1  #define HAVE_ALLOCA   1  #define HAVE_GETENV   1  #define HAVE_PUTENV   1  #define HAVE_UNSETENV  1  #define HAVE_QSORT   1  #define HAVE_ABS   1  //#d

45、efine HAVE_BCOPY   1  //#define HAVE_MEMSET   1  //#define HAVE_MEMCPY   1  //#define HAVE_MEMMOVE   1  //#define HAVE_MEMCMP   1  //#define HAVE_STRLEN   1  //#define HAVE_STRLCPY   1  //#define HAVE_STRLCAT   1  //#define HAVE_STRDUP   1  #define HAVE__STRREV  1  #define HAVE__STRUPR  1

46、  #define HAVE__STRLWR  1  //#define HAVE_INDEX   1  #define HAVE_RINDEX   1  //#define HAVE_STRCHR   1  #define HAVE_STRRCHR  1  #define HAVE_STRSTR   1  #define HAVE_ITOA   1  #define HAVE__LTOA   1  #define HAVE__UITOA   1  #define HAVE__ULTOA   1  #define HAVE_STRTOL   1  #define HAVE

47、STRTOUL  1  #define HAVE__I64TOA  1  #define HAVE__UI64TOA  1  #define HAVE_STRTOLL  1  #define HAVE_STRTOULL  1  #define HAVE_STRTOD   1  #define HAVE_ATOI   1  #define HAVE_ATOF   1  #define HAVE_STRCMP   1  #define HAVE_STRNCMP  1  #define HAVE__STRICMP  1  #define HAVE_STRCASECMP  1

48、  #define HAVE__STRNICMP  1  #define HAVE_STRNCASECMP 1  #define HAVE_SSCANF   1  #define HAVE_SNPRINTF  1  #define HAVE_VSNPRINTF  1  //#define HAVE_ICONV  #define HAVE_SIGACTION  1  #define HAVE_SETJMP   1  #define HAVE_NANOSLEEP  1  //#define HAVE_CLOCK_GETTIME 1  #define HAVE_DLVSYM   1  #def

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服