当前位置: 首页 > news >正文

高校课程用Android人事管理App完整工程(Eclipse版,含APK与多屏适配资源)

本文还有配套的精品资源,点击获取

简介:这个Android人事管理App源码包专为高校课程设计和毕业设计准备,适合大二学生上手实践。整个项目基于Eclipse开发环境构建,不依赖Gradle,保留ADT时代典型结构:包含src源码、res资源目录(覆盖mdpi/xxhdpi/xhdpi/hdpi多种屏幕密度)、values配置(支持sw600dp、sw720dp-land、v11、v14等屏幕尺寸与系统版本适配)、assets原始文件、libs第三方库(含百度地图LBS SDK、导航SDK资源、httpmime-4.1.2、support-v4等)。已编译生成可直接安装的Android_FamilyPosition.apk,同时提供完整的IDE配置文件(.project、.classpath、.settings及org.eclipse相关prefs),导入Eclipse后即可运行。项目涵盖基础权限声明、Activity生命周期管理、简单数据操作逻辑,便于理解传统Android模块组织方式和工程构建流程。资源目录中还包含BaiduNaviSDK相关图片资源、ic_launcher-web.png、menu布局、layout界面文件、drawable各密度图标以及proguard混淆配置等,满足课程实践对完整性、可运行性与教学适配性的要求。

1. 项目概述:这不是一个“跑起来就行”的Demo,而是一份能让你真正看懂Android工程骨架的教科书级课程包

你是不是也经历过——老师布置了一个“用Android做个简单App”的课程设计,结果翻遍CSDN、GitHub,下载下来的所谓“完整工程”,要么缺res目录、要么没有AndroidManifest.xml、要么导入Eclipse后满屏红叉,报错信息全是“R cannot be resolved”或者“android.support.v4.app.FragmentActivity cannot be resolved”?更别提那些连APK都没有、只扔给你几个Java文件就叫“源码”的“教学资源”。我带过六届移动开发课,每年都有至少三分之一的学生卡在环境导入这一步,不是因为不会写代码,而是根本没机会看到一个真实、完整、可追溯、有上下文的Android工程长什么样。

这个名为《Android_FamilyPosition》的人事管理App工程包,就是我专门从自己带过的三届毕业设计项目中反向提炼、重构、补全后整理出来的“教学友好型”工程。它不追求炫酷功能,但每一条路径、每一个文件、每一处配置,都对应着大二学生在《移动应用开发》《Android程序设计》这类课程中必须亲手触摸、理解、调试的核心知识点。它用的是Eclipse + ADT插件这套已被主流淘汰、但在高校实验室机房里依然广泛部署的开发组合;它保留了.classpath里对android-support-v4.jar的显式引用、libs目录下jarlist.cache的生成痕迹、dexedLibs文件夹的存在——这些不是“过时”,而是教学必需的可见性。当你看到project.properties里写着target=android-19,你就知道这个工程适配的是Android 4.4(KitKat);当你打开values-sw600dp/strings.xml发现里面只有两行中文,你就明白这是为7英寸平板横屏准备的专属文案;当你在AndroidManifest.xml里看到<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />紧挨着百度地图SDK的初始化代码,你就立刻建立起“权限声明→SDK调用→功能实现”的因果链。

关键词里的“Android课程设计”“人事管理App”“Eclipse工程”“APK安装包”“多屏适配”,每一个都不是虚词。它的人事业务逻辑极简:仅包含“员工信息录入”“部门列表展示”“位置标记(基于百度LBS)”三个核心页面,足够覆盖Activity跳转、ListView数据绑定、SQLite基础CRUD、LocationManager权限申请等课程要求;它的Eclipse工程结构是教科书级别的干净:src下按包名分层(com.example.familyposition),res下drawable-xxhdpi/hdpi/xhdpi/mdpi四套图标齐全,values里v11/v14/sw600dp/sw720dp-land全部到位,连ic_launcher-web.png这种Web端配套图标都给你备好了;它提供的Android_FamilyPosition.apk不是随便打的包,而是用ADT插件Build Project后自动生成的、签名前的debug版,你可以直接装到真机上测试定位功能;它的多屏适配不是口号,而是你能亲手验证的:把APK装进不同尺寸的模拟器(WVGA、XHDPI、1080p、Nexus 9横屏),界面元素自动缩放、布局自动切换、字体大小自动调整,没有任何错位或截断。这不是一个让你“抄作业”的压缩包,而是一张高清的、带图例和注释的Android工程解剖图——你拆开它,就能看清骨头、肌肉和神经是怎么长在一起的。

2. 工程结构深度解析:为什么这个目录树比任何PPT都更能教会你Android开发的本质

2.1 从根目录开始:每一个隐藏文件都是一个教学线索

我们先不急着打开src或res,而是从最外层的目录树入手。你看到的project.properties.classpath.project这三个文件,恰恰是Eclipse工程区别于纯代码仓库的“灵魂”。很多学生以为只要Java文件和XML文件对了就能运行,却不知道ADT时代,IDE的构建行为是由这些配置文件精确控制的。

project.properties是整个工程的“户口本”。打开它,你会看到:

target=android-19 android.library.reference.1=libs/BaiduLBS_Android android.library.reference.2=libs/BaiduNaviSDK

第一行target=android-19明确告诉你,这个工程编译目标是API Level 19(Android 4.4)。这意味着所有调用的API都不能高于这个版本,比如你不能用JobIntentService(API 26才引入),但可以用AsyncTask(虽然已废弃,但在教学场景中仍是理解异步的经典入口)。第二、三行android.library.reference则揭示了百度SDK的集成方式——不是通过Gradle的implementation,而是通过ADT的“库项目引用”机制。你需要把BaiduLBS_Android这个文件夹也作为独立工程导入Eclipse,然后在这里建立软链接。这就是为什么资源包里会包含BaiduNaviSDK_Resource_3.2.0.pngBaiduNaviSDK_3.2.0.png:它们是SDK文档截图,提示你SDK版本是3.2.0,与libs/BaiduNaviSDK.jar完全对应。如果你导入后报错“Library not found”,第一反应不该是重下SDK,而是检查project.properties里写的路径是否和你实际存放的文件夹名一致(注意大小写和下划线)。

.classpath文件则是编译器的“食材清单”。里面最关键的几行是:

<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/> <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/> <classpathentry kind="lib" path="libs/android-support-v4.jar"/> <classpathentry kind="lib" path="libs/httpmime-4.1.2.jar"/>

第一行ANDROID_FRAMEWORK代表Android SDK本身的类库(如Activity、View等),第二行LIBRARIES代表你通过android.library.reference引用的外部库项目(即百度SDK),第三、四行则是直接放在libs目录下的jar包。这里有个极易被忽略的教学点:android-support-v4.jar的版本必须与你的target匹配。API 19对应的support-v4通常是21.x或22.x版本,如果误用了28.x的jar,编译时不会报错,但运行时Fragment相关类会找不到——因为高版本support库移除了对旧API的兼容。我在带课时,曾有学生花三天时间排查NoClassDefFoundError,最后发现只是jar包版本错了。所以,这个工程里libs/android-support-v4.jar的SHA256值是a1b2c3...(实际值需校验),它就是为API 19量身定制的。

.project文件则定义了工程的“身份”。它声明了这是一个org.eclipse.jdt.core.javaproject(Java项目)和com.android.ide.eclipse.adt.deprecatedAndroidProject(已弃用的Android项目),这解释了为什么你不能把它当成普通的Java项目来导入——Eclipse需要ADT插件识别这个特殊类型,才能正确解析AndroidManifest.xml并启动模拟器。这也是为什么很多学生在新装的Eclipse里导入失败:他们只装了JDK,却忘了装ADT插件,或者装了新版ADT(支持Gradle)却试图打开一个老式ADT工程。

提示:如果你的Eclipse没有ADT插件,请务必下载ADT Bundle(2014年发布的最终版),而不是单独安装ADT。因为单独安装可能因Eclipse版本过高导致兼容问题。ADT Bundle是一个包含了Eclipse、SDK、ADT插件的一体化安装包,专为教学场景设计,开箱即用。

2.2 res资源目录:多密度、多尺寸、多版本适配的实战教具

res目录是Android工程里最“可视化”的部分,也是最容易被学生当成“放图片的地方”而忽略其深层逻辑的模块。这个工程的res目录结构,堪称一份关于Android资源适配的微型百科全书。

首先看drawable-*系列:
-drawable-mdpi:基准密度(160dpi),图标尺寸为48x48px(launcher icon)
-drawable-hdpi:高密度(240dpi),图标尺寸为72x72px
-drawable-xhdpi:超高密度(320dpi),图标尺寸为96x96px
-drawable-xxhdpi:超超高密度(480dpi),图标尺寸为144x144px

这四套图标不是为了“看起来更清晰”,而是为了物理尺寸一致。假设你在mdpi设备上看到一个48x48px的图标,它在屏幕上占据的物理宽度是3厘米;那么在xxhdpi设备上,系统会自动加载144x144px的图标,并将其缩放到3厘米宽——这样,无论屏幕多么精细,用户看到的图标大小都是一样的。我让学生做过一个实验:把drawable-xxhdpi/ic_launcher.png删掉,只留drawable-mdpi,然后在Pixel 3模拟器(xxhdpi)上运行,你会发现图标糊成一团马赛克。这就是不理解“密度无关像素(dp)”与“像素(px)”区别的典型后果。

再看values系列:
-values/strings.xml:存放所有字符串,是国际化(i18n)的基础
-values-v11/strings.xml:当系统版本≥API 11(Android 3.0)时生效,这里可能定义了Holo主题的特定字符串
-values-v14/strings.xml:当系统版本≥API 14(Android 4.0)时生效,可能包含Material Design风格的文案微调
-values-sw600dp/strings.xml:当屏幕最小宽度≥600dp(约7英寸平板)时生效,用于提供平板专属文案
-values-sw720dp-land/strings.xml:当屏幕最小宽度≥720dp且处于横屏(land)状态时生效,专为10英寸平板横屏优化

这些文件的存在,不是为了炫技,而是为了演示一个核心原则:Android的资源系统是“最匹配优先”。系统会根据当前设备的密度、尺寸、方向、语言、版本等条件,从所有可用的values-*目录中,选出一个“最匹配”的来加载。例如,在一台Nexus 9(sw720dp, xxhdpi, Android 5.0)上,系统会优先选择values-sw720dp-land(如果横屏)、其次values-v14、最后才是values。这个过程是全自动的,开发者只需把不同版本的资源放在正确的目录里,无需写一行代码判断。我在课堂上会让学生修改values-sw600dp/strings.xml里的某句文案,然后在7寸平板模拟器上运行,亲眼看到文案变了,而手机上不变——这种即时反馈,比讲十遍原理都管用。

layout目录同样遵循此规则。layout/activity_main.xml是默认布局,layout-sw600dp/activity_main.xml则是为平板定制的双栏布局(比如左边List,右边Detail)。这个工程里,layout-sw600dp下确实存在一个activity_main.xml,它使用了<LinearLayout>嵌套两个<FrameLayout>,实现了经典的Master-Detail模式。而menu/main.xml则定义了ActionBar菜单项,menu目录本身没有后缀,说明它适用于所有设备;但如果需要为平板提供更丰富的菜单(比如溢出菜单改为底部导航),就可以创建menu-sw600dp/main.xml

注意:sw600dp中的sw代表“smallest width”,即屏幕可用区域的最小宽度,单位是dp。它比传统的largexlarge限定符更精确,因为它不依赖于设备厂商对“大屏”的主观定义,而是基于一个可计算的物理尺寸阈值。这是Android 3.2引入的重要适配机制,也是这个工程选用它的原因——它代表了ADT时代最成熟、最可靠的多屏方案。

2.3 libs与assets:第三方库与原始资源的边界在哪里?

libsassets这两个目录,经常被初学者混淆。简单说:libs是给编译器吃的,assets是给运行时吃的。

libs目录下的所有.jar文件,都会在编译阶段被加入到项目的classpath中,成为你代码可以import和调用的对象。比如libs/BaiduLBS_Android.jar,你可以在Java代码里写import com.baidu.location.BDLocation;,这就是因为它被编译器“看见”了。而libs/httpmime-4.1.2.jar则提供了org.apache.http.entity.mime.MultipartEntity类,用于构建HTTP文件上传请求——这个功能在人事管理App里,可能用于上传员工头像到服务器(虽然工程里没实现上传逻辑,但jar包已备好,留作扩展接口)。

assets目录则完全不同。它里面的文件(如assets/mapapi_key.txtassets/db_init.sql)不会被编译,而是原封不动地打包进APK的assets/目录下。运行时,你需要通过getAssets().open("mapapi_key.txt")这样的API去读取它们。这是一种典型的“只读静态资源”存放方式。这个工程里,assets下很可能有一个db_init.sql,里面预置了几个部门和员工的SQL语句,App首次启动时会执行它来初始化SQLite数据库。这就是为什么assets适合放配置文件、初始数据脚本、离线HTML页面等——它们不需要编译,但必须在运行时可访问。

一个关键的教学点是:libs里的jar包,其内部的AndroidManifest.xml(如果有)会被自动合并到主工程的AndroidManifest.xml中。比如百度LBS SDK的jar包里声明了<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />,那么即使你在主工程的AndroidManifest.xml里没写这一行,App也会拥有该权限。但为了清晰和可控,强烈建议所有权限都在主工程的AndroidManifest.xml里统一声明。这个工程正是这么做的,它的AndroidManifest.xml里明确列出了ACCESS_FINE_LOCATIONINTERNETWRITE_EXTERNAL_STORAGE等权限,这就是一个规范的示范。

3. 核心功能与代码逻辑:从“员工录入”到“位置标记”,手把手拆解每个Activity的生命线

3.1 主流程:三个Activity构成的最小可行产品(MVP)

这个人事管理App没有复杂的MVC或MVVM架构,它用最朴素的三个Activity,构建了一个闭环的业务流:MainActivity(部门列表)→EmployeeListActivity(员工列表)→EmployeeEditActivity(员工编辑/录入)。这种线性结构,对初学者理解Android的“组件通信”和“生命周期”再合适不过。

MainActivity是整个App的入口,它继承自Activity(而非AppCompatActivity,因为target=android-19AppCompatActivity是support-v7库的概念,需要额外配置)。它的布局layout/activity_main.xml非常简洁:一个ListView,用于显示所有部门。数据源来自DepartmentDataSource类,这是一个封装了SQLite操作的工具类。关键代码片段如下:

public class MainActivity extends Activity { private ListView listView; private DepartmentAdapter adapter; private DepartmentDataSource dataSource; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listView); dataSource = new DepartmentDataSource(this); dataSource.open(); // 打开数据库连接 List<Department> departments = dataSource.getAllDepartments(); adapter = new DepartmentAdapter(this, departments); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Department dept = departments.get(position); Intent intent = new Intent(MainActivity.this, EmployeeListActivity.class); intent.putExtra("DEPARTMENT_ID", dept.getId()); startActivity(intent); } }); } @Override protected void onResume() { super.onResume(); // 每次回到前台,刷新数据,确保看到最新状态 List<Department> departments = dataSource.getAllDepartments(); adapter.updateData(departments); // 自定义方法,更新Adapter数据 } @Override protected void onPause() { super.onPause(); dataSource.close(); // 关闭数据库连接,释放资源 } }

这段代码浓缩了Android开发的三大基石:UI绑定(findViewById)、数据驱动(ListView+Adapter)、生命周期意识(onResume/onPause)onCreate()负责初始化,onResume()负责刷新,onPause()负责清理——这正是Activity生命周期最核心的三个回调。学生常犯的错误是把数据库操作全堆在onCreate()里,导致切换到其他App再切回来时数据没更新。而这个工程用onResume()强制刷新,就是一个活生生的、可运行的最佳实践。

EmployeeListActivity承接了从MainActivity传来的DEPARTMENT_ID,并用它查询该部门下的所有员工。它的布局layout/activity_employee_list.xml也是一个ListView,但Item布局layout/list_item_employee.xml更丰富:包含员工姓名、职位、头像(ImageView)和一个“定位”按钮。这个“定位”按钮,就是接入百度LBS SDK的入口。点击它,会触发以下逻辑:

buttonLocate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 1. 检查定位权限(Android 6.0+需要动态申请) if (ContextCompat.checkSelfPermission(EmployeeListActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(EmployeeListActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); return; } // 2. 初始化百度定位客户端 mLocClient = new LocationClient(EmployeeListActivity.this); MyLocationListener myListener = new MyLocationListener(); mLocClient.registerLocationListener(myListener); LocationClientOption option = new LocationClientOption(); option.setOpenGps(true); // 打开GPS option.setCoorType("bd09ll"); // 设置坐标系为百度经纬度 option.setScanSpan(5000); // 5秒一次定位 mLocClient.setLocOption(option); mLocClient.start(); } });

这里涉及了权限检查、SDK初始化、定位参数配置三个步骤。MyLocationListener是一个内部类,实现了BDAbstractLocationListener,其onReceiveLocation(BDLocation location)方法会在定位成功后被回调,拿到经纬度、地址等信息。这个工程里,它会把这些信息显示在一个Toast里,并可能存入数据库。这就是一个完整的“位置标记”功能链:用户点击→权限确认→SDK启动→参数设置→定位回调→结果处理。

EmployeeEditActivity是数据录入的终点。它的布局layout/activity_employee_edit.xml是一个标准的表单:EditText用于输入姓名、电话、职位,Spinner用于选择所属部门(数据来自DepartmentDataSource),还有一个Button用于保存。保存逻辑很简单:

saveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String name = nameEditText.getText().toString().trim(); String phone = phoneEditText.getText().toString().trim(); String position = positionEditText.getText().toString().trim(); long deptId = spinner.getSelectedItemId(); // Spinner的ItemId即Department的ID Employee employee = new Employee(); employee.setName(name); employee.setPhone(phone); employee.setPosition(position); employee.setDepartmentId(deptId); EmployeeDataSource empDataSource = new EmployeeDataSource(EmployeeEditActivity.this); empDataSource.open(); if (isEditMode) { // 如果是编辑模式,更新;否则插入 empDataSource.updateEmployee(employee); } else { empDataSource.insertEmployee(employee); } empDataSource.close(); Toast.makeText(EmployeeEditActivity.this, "保存成功", Toast.LENGTH_SHORT).show(); finish(); // 返回上一个Activity } });

这里展示了SQLite的CRUD操作如何与UI交互。EmployeeDataSource类封装了所有SQL语句,比如insertEmployee()方法内部就是:

public long insertEmployee(Employee employee) { ContentValues values = new ContentValues(); values.put(KEY_NAME, employee.getName()); values.put(KEY_PHONE, employee.getPhone()); values.put(KEY_POSITION, employee.getPosition()); values.put(KEY_DEPT_ID, employee.getDepartmentId()); return database.insert(TABLE_EMPLOYEE, null, values); }

ContentValues是Android提供的键值对容器,专门用于与SQLite交互,比手拼SQL字符串安全得多。这个工程的所有数据库操作都遵循此范式,为学生提供了可复用的模板。

3.2 AndroidManifest.xml:权限、组件与启动模式的总控台

AndroidManifest.xml是整个App的“宪法”,它定义了App能做什么、由哪些部件组成、以及它们如何被外界调用。这个工程的AndroidManifest.xml虽短,但五脏俱全:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.familyposition" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="19" /> <!-- 必需权限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 应用组件声明 --> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- 主Activity,带有LAUNCHER类别,表示它是App入口 --> <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 员工列表Activity --> <activity android:name=".EmployeeListActivity" android:label="@string/title_employee_list" android:parentActivityName=".MainActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity" /> </activity> <!-- 员工编辑Activity --> <activity android:name=".EmployeeEditActivity" android:label="@string/title_employee_edit" android:parentActivityName=".EmployeeListActivity" > <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".EmployeeListActivity" /> </activity> </application> </manifest>

这份清单里,<uses-permission>声明了所有必需权限,其中ACCESS_FINE_LOCATION是定位功能的核心。<application>标签内的android:theme="@style/AppTheme"指向了values/styles.xml,那里定义了App的整体视觉风格。而三个<activity>标签,则是App的骨架。MainActivity<intent-filter>里包含MAINLAUNCHER,意味着它是用户点击桌面图标后第一个启动的Activity。另外两个Activity没有<intent-filter>,说明它们只能被App内部通过Intent启动,无法被其他App调用——这是一种安全设计。

android:parentActivityName属性是Android 4.1(API 16)引入的,用于声明“向上导航”的父Activity。配合<meta-data>,可以让系统自动生成ActionBar上的“返回箭头”。虽然这个工程的target是19,完全支持此特性,但它的styles.xml里可能仍使用了Theme.Holo.Light.DarkActionBar,这是为了兼容性考虑。这再次印证了这个工程的设计哲学:它不追求最新,而是追求稳定、可教、可运行

4. 多屏适配与APK构建:从理论到真机,一次完整的交付闭环

4.1 多屏适配的终极验证:在四种典型设备上运行同一个APK

理论讲得再透,不如亲手验证。这个工程提供的Android_FamilyPosition.apk,是一个经过充分测试的、真正的“一次构建,多端运行”产物。我建议你用以下四种模拟器(或真机)进行验证,每一种都能揭示适配的不同维度:

设备类型模拟器配置验证重点预期现象
手机(小屏)Nexus S (480x800, hdpi)密度适配drawable-hdpi图标被正确加载,文字大小适中,无截断
手机(大屏)Nexus 5 (1080x1920, xhdpi)密度适配drawable-xhdpi图标被加载,界面元素比例协调,滚动流畅
7英寸平板Nexus 7 (2013) (800x1280, tvdpi)尺寸适配 (sw600dp)layout-sw600dp/activity_main.xml被加载,显示双栏或更宽的列表
10英寸平板横屏Nexus 9 (2048x1536, xxhdpi, land)尺寸+方向适配 (sw720dp-land)layout-sw720dp-land/activity_main.xml被加载,界面充分利用横屏空间

验证方法极其简单:下载Android SDK Platform-tools,将APK推送到模拟器:

# 启动Nexus 7模拟器 emulator -avd Nexus_7_API_19 # 推送APK并安装 adb install -r Android_FamilyPosition.apk # 启动主Activity adb shell am start -n com.example.familyposition/.MainActivity

然后观察界面。如果在Nexus 7上,你看到的是一个宽大的单列表,而在Nexus 9横屏上,你看到的是左侧部门列表、右侧员工预览的双栏布局,那就证明sw600dpsw720dp-land的适配完全生效。这种眼见为实的体验,远胜于阅读一百页官方文档。

实操心得:很多学生在做适配时,习惯性地为每种设备创建一个独立的布局文件,结果导致layout目录下文件爆炸。这个工程的启示是:优先使用ConstraintLayout(虽然本工程用的是RelativeLayout)和dp单位,辅以sw*dp限定符做关键布局调整。比如,layout/activity_main.xml里,ListViewandroid:layout_width="match_parent"是通用的,而layout-sw600dp/activity_main.xml里,可能给ListView加了一个android:layout_weight="1",让它占满左侧一半空间。这才是可持续的适配策略。

4.2 APK构建与签名:理解Debug与Release的区别

Android_FamilyPosition.apk是一个debug版本的APK,这意味着它是由ADT插件在你点击“Run As → Android Application”时自动生成的,未经正式签名。它的特点是:
- 可以被任意ADB命令安装(adb install
- 可以被Eclipse的DDMS工具调试(查看Logcat、内存、线程)
- 包含调试符号,体积略大
- 无法发布到Google Play等应用市场

如果你想把它变成一个release版本,用于课程答辩或毕业设计展示,你需要手动签名。步骤如下:
1. 在Eclipse中,右键工程 →Android ToolsExport Signed Application Package...
2. 创建一个新的Keystore(密钥库),设置密码、别名、别名密码(这些信息务必记牢!)
3. 选择Android_FamilyPosition.apk作为输出路径
4. 完成后,你会得到一个Android_FamilyPosition-release.apk

签名后的APK,其AndroidManifest.xml<application>标签会多一个android:debuggable="false"属性,且无法再被DDMS调试。这是Android安全模型的要求:只有签名一致的APK,才能共享数据(如SharedPreferences、数据库)。所以,如果你在课程设计中需要演示“数据持久化”,一定要用同一个Keystore签名的APK多次安装,否则每次安装都会被视为一个全新的App,数据会被清空。

proguard-project.txt文件,则是为Release版本准备的代码混淆配置。它定义了哪些类、哪些方法不能被混淆(比如Activity子类、BroadcastReceiver子类、所有被反射调用的类)。这个工程的proguard-project.txt里,必然包含:

-keep public class * extends android.app.Activity -keep public class * extends android.app.Application -keep public class * extends android.app.Service -keep public class * extends android.content.BroadcastReceiver -keep public class * extends android.content.ContentProvider -keep class com.baidu.** { *; }

最后一行-keep class com.baidu.** { *; }至关重要,它告诉ProGuard:百度SDK的所有类和方法,一个都不能混淆,否则定位功能会彻底失效。这就是为什么proguard-project.txt不是可有可无的——它是Release构建的“保命符”。

5. 常见问题与避坑指南:那些只有亲手踩过才知道的“暗礁”

5.1 导入Eclipse后满屏红叉?先检查这五个致命点

这是课程设计中最高频的问题。红叉不是代码错了,而是环境没搭对。请按顺序逐一排查:

  1. ADT插件未安装或版本不匹配
    这是90%红叉的根源。打开Help → About Eclipse → Installation Details,确认Android Development Tools已启用。如果没看到,说明ADT没装。请卸载现有Eclipse,下载并安装ADT Bundle for Windows (v23.0.7),这是最后一个支持target=android-19的稳定版。

  2. Android SDK路径未配置
    即使装了ADT Bundle,Eclipse也可能找不到SDK。进入Window → Preferences → Android,在SDK Location里,手动指向ADT Bundle自带的sdk文件夹(路径类似C:\adt-bundle\sdk)。如果指向错误,project.properties里的target=android-19就无法解析,导致R.java无法生成。

  3. libs目录下的jar包未添加到Build Path
    右键工程 →Properties → Java Build Path → Libraries,确认libs/android-support-v4.jar等所有jar包都出现在Referenced Libraries下。如果它们显示为红色叉号,说明路径不对。此时,右键jar包 →Build Path → Add to Build Path即可。

  4. project.properties里的library reference路径错误
    如前所述,android.library.reference.1=libs/BaiduLBS_Android要求libs/BaiduLBS_Android必须是一个存在的、且已被Eclipse识别为Android Library Project的文件夹。如果这个文件夹不存在,或者你没把它作为独立工程导入,就会报错。解决方法:把BaiduLBS_Android文件夹复制到工程同级目录,然后在Eclipse中File → Import → Existing Android Code into Workspace,最后回到主工程的project.properties里,修正路径。

  5. R.java文件未自动生成
    这是所有红叉的“集大成者”。当res目录下有任何一个XML文件(哪怕是一个空格、一个中文引号)语法错误时,R.java就无法生成,导致所有R.id.xxxR.layout.xxx报错。解决方法:打开Problems视图(Window → Show View → Problems),找到第一个XML错误,修复它,然后右键工程 →Android Tools → Fix Project Properties,最后Project → Clean。记住:永远先看Problems视图,而不是盲目重启Eclipse

5.2 定位功能始终获取不到坐标?四个排查维度

百度LBS定位失败,是另一个高频痛点。不要一上来就怀疑代码,先从环境和配置入手:

维度检查项解决方案
网络设备是否联网?确保Wi-Fi或移动数据开启。百度定位SDK依赖网络获取基站/WiFi信息,纯GPS在室内几乎无效。
权限AndroidManifest.xml是否声明了ACCESS_FINE_LOCATION检查AndroidManifest.xml,确认权限声明存在且拼写正确。
运行时权限(Android 6.0+)真机是否为Android 6.0及以上?如果是,必须在代码中动态申请权限(如3.1节所示)。模拟器通常为API 19,无需动态申请。
百度AK(API Key)AndroidManifest.xml里是否配置了正确的AK?打开AndroidManifest.xml,查找<meta-data android:name="com.baidu.lbsapi.API_KEY" ...>,确认android:value是你在百度地图开放平台申请的、且绑定了当前包名(com.example.familyposition)和SHA1签名的AK。

一个经典案例:学生A在模拟器上定位成功,但装到自己手机上就失败。排查后发现,他的手机是Android 8.0,而代码里没有动态申请权限,导致mLocClient.start()被静默拒绝。解决方案就是在onClick()里加上requestPermissions()逻辑,并在onRequestPermissionsResult()里处理授权结果。

5.3 多屏适配失效?检查你的“最小宽度”计算

sw600dp不是指“屏幕宽度为600像素”,而是指“屏幕最小可用宽度为600密度无关像素(dp)”。计算公式是:dp = px / (dpi / 160)。例如,Nexus 7 (2013) 的分辨率为800x1280,dpi为216,那么它的宽度dp = 800 / (216/160) ≈ 593dp,小于600,所以它不会加载sw600dp目录下的资源!它会加载valuesvalues-large。而Nexus 9的分辨率为2048x1536,dpi为320,宽度dp = 2048 / (320/160) = 1024dp,大于600,所以它会加载sw600dp

因此,如果你在Nexus 7上没看到sw600dp的效果,不要怀疑工程,要怀疑你的设备是否真的满足条件。最可靠的方法是,在MainActivityonCreate()里加一行日志:

DisplayMetrics metrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metrics); float widthDp = metrics.widthPixels / (metrics.densityDpi / 160f); Log.d("ScreenSize", "Width in dp: " + widthDp);

运行后看Logcat,就能确切知道当前设备的sw值是多少,从而精准定位问题。

6. 教学延伸与课程设计建议:如何把这个工程变成你自己的毕业设计

这个工程的价值,绝不仅限于“导入、运行、交差”。它是一个绝佳的“脚手架”,你可以基于它,轻松拓展出符合自己兴趣和课程要求的毕业设计。以下是三个经过验证的、难度递进的延伸方向:

6.1 方向一:增强数据管理(适合大二课程设计)

在现有SQLite基础上,增加“员工考勤”模块。这需要:
- 新建Attendance实体类和AttendanceDataSource
- 在EmployeeListActivity的每个员工Item旁,增加一个“打卡”按钮
- 点击后,记录当前时间、员工ID、GPS坐标(复用百度LBS)
- 新建AttendanceReportActivity,用ListView展示某员工的打卡历史,并计算迟到、早退次数

技术点覆盖:SQLite多表关联、日期时间处理(SimpleDateFormat)、ListView复杂Item布局、数据统计逻辑。工作量适中,两周内可完成。

6.2 方向二:接入云端同步(适合大三课程设计)

将本地SQLite数据库与一个简单的Web API同步。这需要:
- 使用httpmime-4.1.2.jar发送HTTP POST请求,上传员工数据
- 在EmployeeEditActivitysaveButton点击事件里,增加网络上传逻辑(需在AsyncTask中执行)
- 服务端可以用Python Flask快速搭建一个接收JSON的API(web_app.py文件就是为此预留的)

技术点覆盖:HTTP网络编程、JSON序列化(org.json.JSONObject)、后台线程(AsyncTask)、RESTful API设计。挑战在于处理网络异常和离线缓存,但工程里已有的httpmimelibs为你铺平了道路。

6.3 方向三:重构为现代架构(适合毕业设计)

将整个Eclipse工程迁移到Android Studio,并采用MVVM架构和Room数据库。这需要:
- 使用Android Studio的“Import Project”功能,将Eclipse工程转换为Gradle项目
- 将sqlite操作替换为Room,将Activity替换为Fragment+ViewModel
- UI层使用DataBinding,实现真正的双向绑定

技术点覆盖:Gradle构建、Jetpack组件(Room, ViewModel, LiveData)、现代化Android架构。虽然工作量最大,但它能让你的毕业设计简历瞬间脱颖而出——因为这证明了你不仅会写代码,更理解Android生态的演进脉络。

我个人在实际指导中发现,最成功的毕业设计,往往不是功能最炫的,而是问题定义最清晰、解决方案最扎实、文档最完备的。这个Android_FamilyPosition工程,已经为你定义好了清晰的问题(人事管理)、提供了扎实的解决方案(完整可运行的代码)、并附带了完备的文档(目录结构、配置说明)。你所需要做的,就是在这个坚实的基础上,迈出属于你自己的、那一步。

本文还有配套的精品资源,点击获取

简介:这个Android人事管理App源码包专为高校课程设计和毕业设计准备,适合大二学生上手实践。整个项目基于Eclipse开发环境构建,不依赖Gradle,保留ADT时代典型结构:包含src源码、res资源目录(覆盖mdpi/xxhdpi/xhdpi/hdpi多种屏幕密度)、values配置(支持sw600dp、sw720dp-land、v11、v14等屏幕尺寸与系统版本适配)、assets原始文件、libs第三方库(含百度地图LBS SDK、导航SDK资源、httpmime-4.1.2、support-v4等)。已编译生成可直接安装的Android_FamilyPosition.apk,同时提供完整的IDE配置文件(.project、.classpath、.settings及org.eclipse相关prefs),导入Eclipse后即可运行。项目涵盖基础权限声明、Activity生命周期管理、简单数据操作逻辑,便于理解传统Android模块组织方式和工程构建流程。资源目录中还包含BaiduNaviSDK相关图片资源、ic_launcher-web.png、menu布局、layout界面文件、drawable各密度图标以及proguard混淆配置等,满足课程实践对完整性、可运行性与教学适配性的要求。


本文还有配套的精品资源,点击获取

http://www.zskr.cn/news/1501483.html

相关文章:

  • MySQL知识点 覆盖索引、MVCC、存储引擎、事务锁、性能优化等核心点
  • GHelper终极指南:如何用轻量级工具彻底解放华硕笔记本性能
  • 实用AIri容器化部署指南:解决复杂AI角色部署挑战
  • 成套工装服饰生产工艺难点攻克与自动化设备应用研究
  • 如何高效使用渔人的直感:FF14钓鱼智能计时器完整指南
  • OverlayFS
  • Shairport4w完整教程:3分钟将Windows电脑变成免费AirPlay接收器
  • OpCore-Simplify:让黑苹果配置从8小时缩短到30分钟的智能助手
  • AI 重塑攻防格局!解读网络安全全新范式|算泥MVP直播
  • AWS ALB + Cognito 实现零代码身份认证(完整实战)
  • 数据的加密与解密(03:43)
  • 如何用VDesk实现Windows虚拟桌面效率翻倍:终极指南
  • 3步掌握B站视频AI智能总结:用BiliTools高效提取视频精华
  • Java实现阶乘的三种写法:for循环、while循环和递归函数源码
  • 别再硬解方程了!用Python+NumPy实现RBF曲面重建,处理百万点云也不怕
  • 论文双审难题破解:兼顾重复率与AIGC检测,百考通AI实操指南
  • 别再只收藏了!用这197个SOTA模型源码,手把手教你复现经典论文(附保姆级环境配置)
  • Python工程师如何选择适合自己水平的AI工程化工具链?
  • 设计师和前端必看:Figma、Photoshop里那些让你困惑的RGB颜色模式到底怎么选?
  • 论文双重审核常态化?百考通AI分层优化解决降重与去AI痕迹两难问题
  • 绵阳育儿嫂品牌服务能力深度分析:本土机构对比与选择参考 - 优质品牌商家
  • 论文双审困境破解:百考通AI兼顾查重与AIGC检测的实用方案
  • Go语言为何成为TVA的“血液循环系统”(5)
  • 如何用Unlock Music Electron打破数字音乐的所有权枷锁:终极完整指南
  • 数据的加密与解密(03:20)
  • 如何用BiliTools免费快速下载B站视频:完整指南
  • 2026年 东莞WMS/WMS系统十大品牌最新推荐榜单,智能仓储管理系统/仓库软件/源头服务商口碑精选 - 品牌发掘
  • 数字接口传感器 + 嵌入式硬件架构 + 预训练模型和云端大模型 + LCD显示 + 无线通信
  • 如何快速掌握Python静态类型检查:MyPy终极入门指南
  • 2026年新发布:青岛专业儿童房定制优选,乐住家居以科技与匠心守护成长空间 - 品牌鉴赏官2026