版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
《移动智能终端程序设计》课程结业作品Android记事本程序设计说明书班级:信息管理与信息系统姓名:王成科学号:荆楚理工学院计算机工程学院目录一、需求分析 3二、可行性分析 3三、设计目标 33.1、项目功能模块划分 33.2、UI设计 33.3、图形设计 3四、系统设计-功能结构设计 44.1、新建笔记 44.2、修改笔记 44.3、删除笔记 4五、数据库设计 45.1、笔记表-notes 45.2、多媒体信息表-media 5六、架构设计 5七、代码开发及工作分配 57.1、主页面/笔记列表显示页面的布局代码: 57.2、编辑笔记页面的布局代码: 67.3、显示多媒体列表的条目布局: 77.4、显示笔记列表的条目布局: 77.5、主页面/笔记列表显示页面的java代码 87.6、编辑笔记页面的java代码: 117.7、显示图片的页面: 187.8、显示视频的页面: 197.9、操作数据库的类: 197.10、manifest文件代码: 21八、测试 228.1、测试功能和操作方式: 228.2、测试结果 22参考文献 23一、需求分析一个记事本,能够输入标题和内容,创建日期、最新修改日期等信息。如果没有输入标题则使用内容的第一句话作为标题,创建日期和修改日期均由系统自动生成,无需用户干预。提供笔记列表,列表中笔记展示位标题、创建日期/修改日期高级的可以给笔记添加照片或视频,这既可以自己拍摄也可以添加手机中已有的视频。二、可行性分析技术可行,安卓记事本在技术上已经非常成熟,所以在这方面有很多地方可以参考别人的。经济可行,安卓记事本开发成本低,使用效率高,同事这个作品是作为练习使用,提高自己开发能力。技术方面主要用到Java,SQLite,listview、Intent等知识点。三、设计目标3.1、项目功能模块划分打开应用的第一个页面用于展示已有的笔记列表,列表中的每一个笔记条目都可以点击,点击之后呈现此笔记的完整内容/编辑页面,列表下方有一个添加笔记的按钮,还有拍照笔记,摄像笔记,能够增加、保存、更改、删除笔记。3.2、UI设计测试用户界面(如菜单、对话框、窗口和其它可规控件)布局、风格是否满足客户要求、文字是否正确、页面是否美观、文字、图片组合是否完美、操作是否友好等。
UI测试的目标是确保用户界面会通过测试对象的功能来为用户提供相应的访问或浏觅功能。确保用户界面符合公司或行业的标准。包括用户友好性、人性化、易操作性测试3.3、图形设计输入框说明文字的内容与系统功能是否一致,文字长度是否加以限制,文字内容是否表意不明,是否有错别字,信息是否为中文显示,是否有敏感性词汇、关键词,是否有敏感性图片,如:涉及版权、专利、隐私等图片。四、系统设计-功能结构设计uml建模工具的使用:4.1、新建笔记点击添加笔记按钮→打开编辑笔记页面→用户分别在标题栏和内容栏输入内容;点击添加视频时,打开系统录像拍摄视频并保存,然后在多媒体列表中显示视频图片、文件名称、路径;点击添加图像时,打开照相机拍摄图片并保存,然后在多媒体列表中显示图像图片、文件名称、路径;→点击保存按钮,将笔记和多媒体信息保存到数据库;→点击取消按钮,关闭当前页面,返回主页面/笔记列表页面。4.2、修改笔记点击笔记列表中的笔记时,打开编辑笔记页面,并传入当前笔记的信息,在编辑页面有用户对笔记操作,跟新建笔记的操作相同4.3、删除笔记选择已有笔记,进行数据库删除操作。4.4、保存笔记将编辑页面里的笔记信息存入到笔记数据库表中,多媒体信息存入到多媒体数据库表中五、数据库设计5.1、笔记表-notesid-Integer型、主键、自动增加INTEGERPRIMARYKEYAUTOINCREMENT,name-text型,不为空,默认为“”TEXTNOTNULLDEFAULT\"\",content,text型,不为空,默认为“”TEXTNOTNULLDEFAULT\"\",date,text型,不为空,默认为“”TEXTNOTNULLDEFAULT\"\",5.2、多媒体信息表-mediaid-Integer型、主键、自动增加INTEGERPRIMARYKEYAUTOINCREMENT,path-text型,不为空,默认为“”TEXTNOTNULLDEFAULT\"\",note_id-Integer型,不为空,默认为0INTEGERNOTNULLDEFAULT0六、架构设计模块与模块之间的通信机制,MVC、分层都是三层:视图层(PresentationLayer)、控制层(DomainLayer)、数据流层(DataLayer)。视图层,使用LinearLayout,列表使用ListView七、代码开发及工作分配7.1、主页面/笔记列表显示页面的布局代码:/Notes/res/layout/activity_main.xml<LinearLayoutxmlns:androidapk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity"><ListViewandroid:id="@android:id/list"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="1"></ListView><Buttonandroid:id="@+id/btnAddNote"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="添加日志"/></LinearLayout>7.2、编辑笔记页面的布局代码:/Notes/res/layout/aty_eidt_note.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:androidapk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><EditTextandroid:id="@+id/etName"android:layout_width="match_parent"android:layout_height="wrap_content"android:ems="10"android:singleLine="true"><requestFocus/></EditText><EditTextandroid:id="@+id/etContent"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="1"android:ems="10"android:gravity="top"/><ListViewandroid:id="@android:id/list"android:layout_width="fill_parent"android:layout_height="wrap_content"android:layout_weight="2"></ListView><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnSave"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="保存"/><Buttonandroid:id="@+id/btnCancel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="取消"/><Buttonandroid:id="@+id/btnAddPhoto"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_weight="1"android:text="拍照"/><Buttonandroid:id="@+id/btnAddVideo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="录像"android:layout_weight="1"/></LinearLayout></LinearLayout>7.3、显示多媒体列表的条目布局:/Notes/res/layout/media_list_cell.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:androidapk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:gravity="center_vertical"><ImageViewandroid:id="@+id/ivIcon"android:layout_width="80dp"android:layout_height="80dp"/><TextViewandroid:id="@+id/tvPath"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceLarge"/></LinearLayout>7.4、显示笔记列表的条目布局:/Notes/res/layout/notes_list_cell.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:androidapk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/tvName"android:layout_width="match_parent"android:layout_height="wrap_content"android:textAppearance="?android:attr/textAppearanceLarge"/><TextViewandroid:id="@+id/tvDate"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>7.5、主页面/笔记列表显示页面的java代码/Notes/src/com/tops/notes/MainActivity.javapackage;import;import;import;import;import;import;import;import;import;import;import;importandr;/***继承ListActivity的Activity,呈现已经存在的日志和添加日志按钮**@authorTOPS**/publicclassMainActivityextendsListActivity{ privateSimpleCursorAdapteradapter=null; privateNotesDBdb; privateSQLiteDatabasedbRead; publicstaticfinalintREQUEST_CODE_ADD_NOTE=1; publicstaticfinalintREQUEST_CODE_EDIT_NOTE=2; /** *实现OnClickListener接口,添加日志按钮的监听 */ privateOnClickListenerbtnAddNote_clickHandler=newOnClickListener(){ @Override publicvoidonClick(Viewv){ //有返回结果的开启编辑日志的Activity, //requestCodeIf>=0,thiscodewillbereturned //inonActivityResult()whentheactivityexits. startActivityForResult(newIntent(MainActivity.this, AtyEditNote.class),REQUEST_CODE_ADD_NOTE); } }; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(); //操作数据库 db=newNotesDB(this); dbRead=db.getReadableDatabase(); //查询数据库并将数据显示在ListView上。 //建议使用CursorLoader,这个操作因为在UI线程,容易引起无响应错误 adapter=newSimpleCursorAdapter(this,,null, newString[]{NotesDB.COLUMN_NAME_NOTE_NAME, NotesDB.COLUMN_NAME_NOTE_DATE},newint[]{ ,}); setListAdapter(adapter); refreshNotesListView(); findViewById().setOnClickListener( btnAddNote_clickHandler); } /** *复写方法,笔记列表中的笔记条目被点击时被调用,打开编辑笔记页面,同事传入当前笔记的信息 */ @Override protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){ //获取当前笔记条目的Cursor对象 Cursorc=adapter.getCursor(); c.moveToPosition(position); //显式Intent开启编辑笔记页面 Intenti=newIntent(MainActivity.this,AtyEditNote.class); //传入笔记id,name,content i.putExtra(AtyEditNote.EXTRA_NOTE_ID, c.getInt(c.getColumnIndex(NotesDB.COLUMN_NAME_ID))); i.putExtra(AtyEditNote.EXTRA_NOTE_NAME, c.getString(c.getColumnIndex(NotesDB.COLUMN_NAME_NOTE_NAME))); i.putExtra(AtyEditNote.EXTRA_NOTE_CONTENT, c.getString(c.getColumnIndex(NotesDB.COLUMN_NAME_NOTE_CONTENT))); //有返回的开启Activity startActivityForResult(i,REQUEST_CODE_EDIT_NOTE); super.onListItemClick(l,v,position,id); } /** *Calledwhenanactivityyoulaunchedexits,givingyoutherequestCode *youstarteditwith当被开启的Activity存在并返回结果时调用的方法 * *当从编辑笔记页面返回时调用,刷新笔记列表 */ @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ switch(requestCode){ caseREQUEST_CODE_ADD_NOTE: caseREQUEST_CODE_EDIT_NOTE: if(resultCode==Activity.RESULT_OK){ refreshNotesListView(); } break; default: break; } super.onActivityResult(requestCode,resultCode,data); } /** *刷新笔记列表,内容从数据库中查询 */ publicvoidrefreshNotesListView(){ /** *Changetheunderlyingcursortoanewcursor.Ifthereisanexisting *cursoritwillbeclosed. * *Parameters:cursorThenewcursortobeused */ adapter.changeCursor(dbRead.query(NotesDB.TABLE_NAME_NOTES,null,null, null,null,null,null)); }}7.6、编辑笔记页面的java代码:/Notes/src/com/tops/notes/AtyEditNote.javapackage;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;import;publicclassAtyEditNoteextendsListActivity{ privateintnoteId=-1; privateEditTextetName,etContent; privateMediaAdapteradapter; privateNotesDBdb; privateSQLiteDatabasedbRead,dbWrite; privateStringcurrentPath=null; publicstaticfinalintREQUEST_CODE_GET_PHOTO=1; publicstaticfinalintREQUEST_CODE_GET_VIDEO=2; publicstaticfinalStringEXTRA_NOTE_ID="noteId"; publicstaticfinalStringEXTRA_NOTE_NAME="noteName"; publicstaticfinalStringEXTRA_NOTE_CONTENT="noteContent"; /** *按钮点击的监听器,实现OnClickListener接口 */ privateOnClickListenerbtnClickHandler=newOnClickListener(){ Intenti; Filef; @Override publicvoidonClick(Viewv){ switch(v.getId()){ case://添加照片按钮 //使用Intent调用系统照相机,传入图像保存路径和名称 i=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); f=newFile(getMediaDir(),System.currentTimeMillis()+".jpg"); if(!f.exists()){ try{ f.createNewFile(); }catch(IOExceptione){ e.printStackTrace(); } } currentPath=f.getAbsolutePath(); i.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(f)); startActivityForResult(i,REQUEST_CODE_GET_PHOTO); break; case://添加视频按钮 //使用Intent调用系统录像器,传入视频保存路径和名称 i=newIntent(MediaStore.ACTION_VIDEO_CAPTURE); f=newFile(getMediaDir(),System.currentTimeMillis()+".mp4"); if(!f.exists()){ try{ f.createNewFile(); }catch(IOExceptione){ e.printStackTrace(); } } currentPath=f.getAbsolutePath(); i.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(f)); startActivityForResult(i,REQUEST_CODE_GET_VIDEO); break; case://保存按钮 //保存多媒体信息和笔记信息到数据库,然后关闭当前页面,返回到笔记列表页面/主页面 saveMedia(saveNote()); setResult(RESULT_OK); finish(); break; case://取消按钮 //关闭当前页面,返回到笔记列表页面/主页面 setResult(RESULT_CANCELED); finish(); break; default: break; } } }; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(); db=newNotesDB(this); dbRead=db.getReadableDatabase(); dbWrite=db.getWritableDatabase(); //显示多媒体列表 adapter=newMediaAdapter(this); setListAdapter(adapter); etName=(EditText)findViewById(); etContent=(EditText)findViewById(); //获取Activity传递过来的noteId noteId=getIntent().getIntExtra(EXTRA_NOTE_ID,-1); if(noteId>-1){ etName.setText(getIntent().getStringExtra(EXTRA_NOTE_NAME)); etContent.setText(getIntent().getStringExtra(EXTRA_NOTE_CONTENT)); //查询本笔记的noteId并且检查是否有对应的多媒体,有则遍历显示在MediaList中 Cursorc=dbRead.query(NotesDB.TABLE_NAME_MEDIA,null, NotesDB.COLUMN_NAME_MEDIA_OWNER_NOTE_ID+"=?", newString[]{noteId+""},null,null,null); while(c.moveToNext()){ adapter.add(newMediaListCellData(c.getString(c .getColumnIndex(NotesDB.COLUMN_NAME_MEDIA_PATH)),c .getInt(c.getColumnIndex(NotesDB.COLUMN_NAME_ID)))); } /** *Notifiestheattachedobserversthattheunderlyingdatahasbeen *changedandanyViewreflectingthedatasetshouldrefresh *itself. */ adapter.notifyDataSetChanged(); } findViewById().setOnClickListener(btnClickHandler); findViewById(R.id.btnCancel).setOnClickListener(btnClickHandler); findViewById(R.id.btnAddPhoto).setOnClickListener(btnClickHandler); findViewById(R.id.btnAddVideo).setOnClickListener(btnClickHandler); } @Override protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){ MediaListCellDatadata=adapter.getItem(position); Intenti; switch(data.type){ caseMediaType.PHOTO: i=newIntent(this,AtyPhotoViewer.class); i.putExtra(AtyPhotoViewer.EXTRA_PATH,data.path); startActivity(i); break; caseMediaType.VIDEO: i=newIntent(this,AtyVideoViewer.class); i.putExtra(AtyVideoViewer.EXTRA_PATH,data.path); startActivity(i); break; } super.onListItemClick(l,v,position,id); } @Override protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){ (data); switch(requestCode){ caseREQUEST_CODE_GET_PHOTO: caseREQUEST_CODE_GET_VIDEO: if(resultCode==RESULT_OK){ adapter.add(newMediaListCellData(currentPath)); adapter.notifyDataSetChanged(); } break; default: break; } super.onActivityResult(requestCode,resultCode,data); } /** *获取存储Media的目录路径 * *@returnFile类型的目录路径 */ publicFilegetMediaDir(){ Filedir=newFile(Environment.getExternalStorageDirectory(), "NotesMedia"); if(!dir.exists()){ dir.mkdirs(); } returndir; } /** *保存Media信息到数据库 * *@paramnoteId */ publicvoidsaveMedia(intnoteId){ MediaListCellDatadata; ContentValuescv; for(inti=0;i<adapter.getCount();i++){ data=adapter.getItem(i); if(data.id<=-1){ cv=newContentValues(); cv.put(NotesDB.COLUMN_NAME_MEDIA_PATH,data.path); cv.put(NotesDB.COLUMN_NAME_MEDIA_OWNER_NOTE_ID,noteId); dbWrite.insert(NotesDB.TABLE_NAME_MEDIA,null,cv); } } } /** *保存日志到数据库 * *@return */ publicintsaveNote(){ ContentValuescv=newContentValues(); cv.put(NotesDB.COLUMN_NAME_NOTE_NAME,etName.getText().toString()); cv.put(NotesDB.COLUMN_NAME_NOTE_CONTENT,etContent.getText().toString()); cv.put(NotesDB.COLUMN_NAME_NOTE_DATE,newSimpleDateFormat( "yyyy-MM-ddhh:mm:ss").format(newDate())); if(noteId>-1){ dbWrite.update(NotesDB.TABLE_NAME_NOTES,cv,NotesDB.COLUMN_NAME_ID +"=?",newString[]{noteId+""}); returnnoteId; }else{ return(int)dbWrite.insert(NotesDB.TABLE_NAME_NOTES,null,cv); } } /** *复写Activity的生命周期方法,用于关闭读写数据库的操作 */ @Override protectedvoidonDestroy(){ dbRead.close(); dbWrite.close(); super.onDestroy(); } /** *继承BaseAdapter类的MediaAdapter类,用于显示媒体信息 * *@authorTOPS * */ staticclassMediaAdapterextendsBaseAdapter{ privateContextcontext; privateList<MediaListCellData>list=newArrayList<AtyEditNote.MediaListCellData>(); publicMediaAdapter(Contextcontext){ this.context=context; } publicvoidadd(MediaListCellDatadata){ list.add(data); } @Override publicintgetCount(){ returnlist.size(); } @Override publicMediaListCellDatagetItem(intposition){ returnlist.get(position); } @Override publiclonggetItemId(intposition){ returnposition; } @Override publicViewgetView(intposition,ViewconvertView,ViewGroupparent){ if(convertView==null){ convertView=LayoutInflater.from(context).inflate( ,null); } MediaListCellDatadata=getItem(position); ImageViewivIcon=(ImageView)convertView .findViewById(); TextViewtvPath=(TextView)convertView.findViewById(); ivIcon.setImageResource(data.iconId); tvPath.setText(data.path); returnconvertView; } } /** *显示多媒体的条目类 * *@authorTOPS * */ staticclassMediaListCellData{ inttype=0; intid=-1; Stringpath=""; inticonId=; publicMediaListCellData(Stringpath,intid){ this(path); this.id=id; } publicMediaListCellData(Stringpath){ this.path=path; if(path.endsWith(".jpg")){ iconId=; type=MediaType.PHOTO; }elseif(path.endsWith(".mp4")){ iconId=; type=MediaType.VIDEO; } } } /** *多媒体的种类 * *@authorTOPS * */ staticclassMediaType{ staticfinalintPHOTO=1; staticfinalintVIDEO=2; }}7.7、显示图片的页面:/Notes/src/com/tops/notes/AtyPhotoViewer.javapackage;import;import;import;import;import;/***显示照片的Activity**@authorTOPS**/publicclassAtyPhotoViewerextendsActivity{ privateImageViewiv; publicstaticfinalStringEXTRA_PATH="path"; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); iv=newImageView(this); setContentView(iv); Stringpath=getIntent().getStringExtra(EXTRA_PATH); if(path!=null){ iv.setImageURI(Uri.fromFile(newFile(path))); }else{ finish(); } }}7.8、显示视频的页面:/Notes/src/com/tops/notes/AtyVideoViewer.javapackage;import;import;import;import;/***显示视频的Activity**@authorTOPS**/publicclassAtyVideoViewerextendsActivity{ privateVideoViewvv; publicstaticfinalStringEXTRA_PATH="path"; @Override protectedvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); vv=newVideoView(this); vv.setMediaController(newMediaController(this)); setContentView(vv); Stringpath=getIntent().getStringExtra(EXTRA_PATH); if(path!=null){ vv.setVideoPath(path); }else{ finish(); } }}7.9、操作数据库的类:/Notes/src/com/tops/notes/db/NotesDB.javapackage;import;import;import;/***实现SQLiteOpenHelper接口的NotesDB类,用于创建数据库表**@authorTOPS**/publicclassNotesDBextendsSQLiteOpenHelper{ publicstaticfinalStringTABLE_NAME_NOTES="notes"; publicstaticfinalStringTABLE_NAME_MEDIA="media"; publicstaticfinalStringCOLUMN_NAME_ID="_id"; publicstaticfinalStringCOLUMN_NAME_NOTE_NAME="name"; publicstaticfinalStringCOLUMN_NAME_NOTE_CONTENT="content"; publicstaticfinalStringCOLUMN_NAME_NOTE_DATE="date"; publicstaticfinalStringCOLUMN_NAME_MEDIA_PATH="path"; publicstaticfinalStringCOLUMN_NAME_MEDIA_OWNER_NOTE_ID="note_id"; publicNotesDB(Contextcontext){ super(context,"notes",null,1); } /** *当第一次打开数据库,表不存在时调用,以创建表 */ @Override publicvoidonCreate(SQLiteDatabasedb){ db.execSQL("CREATETABLE"+TABLE_NAME_NOTES+"("+COLUMN_NAME_ID +"INTEGERPRIMARYKEYAUTOINCREMENT,"+COLUMN_NAME_NOTE_NAME +"TEXTNOTNULLDEFAULT\"\","+COLUMN_NAME_NOTE_CONTENT +"TEXTNOTNULLDEFAULT\"\","+COLUMN_NAME_NOTE_DATE +"TEXTNOTNULLDEFAULT\"\""+")"); db.execSQL("CREATETABLE"+TABLE_NAME_MEDIA+"("+COLUMN_NAME_ID +"INTEGERPRIMARYKEYAUTOINCREMENT," +COLUMN_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 工程技术咨询服务合同(7篇)
- 医务人员个人工作总结范文(6篇)
- 农贸市场商铺摊位营销方案(5篇)
- 虚拟改装体验研究-洞察分析
- 溯源体系经济效益分析-洞察分析
- 游戏社区运营管理-洞察分析
- 文化创意产业竞争力分析洞察-洞察分析
- 虚拟现实艺术互动性研究-洞察分析
- 《物流运输工具》课件
- 网络空间伦理治理-洞察分析
- 宜春古城改造计划书
- 2024年广西北部湾国际港务集团有限公司招聘笔试参考题库含答案解析
- 人力资源部副经理个人述职报告
- 小学一年级科学(上册)期末试卷含参考答案
- 管道工程心得体会
- 感染医师进修总结汇报
- 个性化营养餐定制平台商业计划书
- (完整)小学四年级多位数乘除法400题
- 火电厂运行管理
- 搞笑朗诵我爱上班台词
- 20以内加减法口算题100道计时精编版(共计3500道)可直接打印
评论
0/150
提交评论