目录
四、将下载的项目源码导入到Android项目的对应目录及文件下
前言
经过一学期的学习,《软件工程》这门课程已接近尾声。由此,老师给我们布置了一个实践任务——小米便签项目。具体是由小组合作,部署项目和上传远程git仓库。因为在实践完成过程中发现会出现很多问题,故编写这这篇博客,用来记录问题。希望也能帮到大家,谢谢!
一、软件安装
这里介绍下我用的Android Studio的版本是2024.2.1,SDK版本为API 24,Gradle版本为8.9。
Android Studio官网下载链接https://developer.android.google.cn/studio?hl=en,找到对应版本进行下载,具体的安装方式推荐大家看这篇https://blog.csdn.net/m0_73909612/article/details/137931888。
二、下载小米便签项目源码
首先我们从github上的开源代码仓库上下载小米便签的源码包。下载地址:https://codeload.github.com/MiCode/Notes/zip/master,然后将下载的zip包进行解压。
三、新建项目工程
双击打开Android Studio软件,选择New Project,选择Empty Views Activity,新建一个空项目:
按照下面图示进行配置:
新创建好的项目目录如下:
四、将下载的项目源码导入到Android项目的对应目录及文件下
把原项目的代码内容搬到新建的项目工程中去:
1.首先把项目 Notes-master\src\net\micode\notes 下的包全部导入 Android Studio 的 net\micode\notes 下:
2.把 Notes-master\res 目录下的包全部导入 Android Studio 的 res 中:
(重复的文件选择替换掉这些文件)
3.将以下代码导入到AndroidManifest.xml文件中:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Notesmaster"
tools:targetApi="31">
<activity
android:name=".ui.NotesListActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:uiOptions="splitActionBarWhenNarrow"
android:windowSoftInputMode="adjustPan"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".ui.NoteEditActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:launchMode="singleTop"
android:theme="@style/NoteTheme"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.INSERT_OR_EDIT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.item/text_note" />
<data android:mimeType="vnd.android.cursor.item/call_note" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
<provider
android:name="net.micode.notes.data.NotesProvider"
android:authorities="micode_notes"
android:multiprocess="true" />
<receiver
android:name=".widget.NoteWidgetProvider_2x"
android:label="@string/app_widget2x2"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_2x_info" />
</receiver>
<receiver
android:name=".widget.NoteWidgetProvider_4x"
android:label="@string/app_widget4x4"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.intent.action.PRIVACY_MODE_CHANGED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_4x_info" />
</receiver>
<receiver android:name=".ui.AlarmInitReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name="net.micode.notes.ui.AlarmReceiver"
android:process=":remote" >
</receiver>
<activity
android:name=".ui.AlarmAlertActivity"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:theme="@android:style/Theme.Holo.Wallpaper.NoTitleBar" >
</activity>
<activity
android:name="net.micode.notes.ui.NotesPreferenceActivity"
android:label="@string/preferences_title"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Holo.Light" >
</activity>
<service
android:name="net.micode.notes.gtask.remote.GTaskSyncService"
android:exported="false" >
</service>
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.NoteEditActivity" />
<!-- <activity-->
<!-- android:name=".MainActivity"-->
<!-- android:exported="true">-->
<!-- <intent-filter>-->
<!-- <action android:name="android.intent.action.MAIN" />-->
<!-- <category android:name="android.intent.category.LAUNCHER" />-->
<!-- </intent-filter>-->
<!-- </activity>-->
</application>
</manifest>
五、解决错误
导入完成之后,点击小锤子(Make Model '......')构建项目,然后本次实践任务的重头戏来了,你会发现有很多报错,解决一个来一个。不要慌,我们一个一个来解决:
1.依赖下载:
源码依赖于一个httpcomponents-client组件,以执行网络服务,这里我们需要去下载依赖:
下载链接:https://dlcdn.apache.org//httpcomponents/httpclient/binary/httpcomponents-client-4.5.14-bin.zip
然后将下载好后的zip包解压放在下一目录:
在Android Studio中导入依赖:
选择选择File -> Project Structure ->Dependencies-> All Dependencies -> +->
填写绝对路径,这里根据自己下载的依赖库路径填写。
导入后,会发现build.gradle多了以下内容:
2.报错:找不到符号 notification.setLatestEventInfo...
这时,会出现以下错误:
错误: 找不到符号 notification.setLatestEventInfo(......)
D:\Code\AndroidCode\Notesmaster\app\src\main\java\net\micode\notes\gtask\remote\GTaskASyncTask.java:80: 错误: 找不到符号
notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
^
符号: 方法 setLatestEventInfo(Context,String,String,PendingIntent)
位置: 类型为Notification的变量 notification
解决方法==>注释以下代码:
修改为:
private void showNotification(int tickerId, String content) {
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), PendingIntent.FLAG_IMMUTABLE);
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), PendingIntent.FLAG_IMMUTABLE);
}
Notification.Builder builder = new Notification.Builder(mContext)
.setAutoCancel(true)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(content)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true);
Notification notification=builder.getNotification();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
}
3.报错:switch语句报错Constant expression required
D:\Code\AndroidCode\Notesmaster\app\src\main\java\net\micode\notes\ui\NoteEditActivity.java:511: 错误: 需要常量表达式
case R.id.menu_new_note:
解决办法参考链接:https://blog.csdn.net/mjh1667002013/article/details/134763804
4.报错:jar包冲突
这里是因为我们刚才导入的依赖包有问题,所以在build.gradle里进行修改:
这部分代码有误
修改成:
dependencies {
implementation(libs.appcompat)
implementation(libs.material)
implementation(libs.activity)
implementation(libs.constraintlayout)
implementation(files("E:\\\\mi\\\\Notesmaster\\\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-osgi-4.5.14.jar"))
implementation(files("E:\\\\mi\\\\Notesmaster\\\\httpcomponents-client-4.5.14-bin\\lib\\httpclient-win-4.5.14.jar"))
implementation(files("E:\\\\mi\\\\Notesmaster\\\\httpcomponents-client-4.5.14-bin\\lib\\httpcore-4.4.16.jar"))
testImplementation(libs.junit)
androidTestImplementation(libs.ext.junit)
androidTestImplementation(libs.espresso.core)
}
5.报错:3 files found with path ‘META-INF/DEPENDENCIES’ ...
3 files found with path 'META-INF/DEPENDENCIES'.
Adding a packaging block may help, please refer to
https://developer.android.com/reference/tools/gradle-api/8.3/com/android/build/api/dsl/Packaging
for more information
解决办法:在build.gradle(Module:app)的android字段里面,加上这段代码,排除掉冲突的系统依赖包即可:
packaging {
resources.excludes.add("META-INF/DEPENDENCIES");
resources.excludes.add("META-INF/NOTICE");
resources.excludes.add("META-INF/LICENSE");
resources.excludes.add("META-INF/LICENSE.txt");
resources.excludes.add("META-INF/NOTICE.txt");
}
六、部署虚拟机
到这里,项目部署完成了,我们再次点击Make Module 这个小锤子,终于没有出现报错信息了。
接下来:我们开始部署虚拟机,依次点击:1->2->3.
在这个页面,随便选择一个机型:
下一步,选择API,这里你们可以试一下 35/34,我的电脑不知道什么原因选择这两个都会出现冷启动失败,而网上的解决办法我都进行了尝试,无疑都失败了,最后,我尝试使用了低API,如API 24,发现没有报错。
七、项目展示
最后,点击运行,运行成功!