資源下載
下面是《Android Studio開發(fā)實(shí)戰(zhàn) 從零基礎(chǔ)到App上線(第3版)》一書用到的工具和代碼資源:
1、本書使用的Android Studio版本為Android Studio Dolphin(小海豚版本),最新的安裝包可前往Android官網(wǎng)頁面下載。
2、本書使用的Android NDK版本為r23b,最新的安裝包可前往Android官網(wǎng)頁面下載。
3、本書提供所有示例源碼的demo工程下載,源碼(適配Android5.0到Android12)的下載方式見該書前言末尾的二維碼,獲取ppt課件同樣掃描前言末尾的二維碼。最新的源碼也可訪問我的gitee獲取,gitee地址是android3: 《Android Studio開發(fā)實(shí)戰(zhàn):從零基礎(chǔ)到App上線(第3版)》配套源碼,服務(wù)端的gitee地址是https://gitee.com/aqi00/net_server。?
4、本書第10章使用了一些反編譯和重簽名工具,這些工具的下載頁面是百度網(wǎng)盤 請輸入提取碼?(提取碼93i5)
5、書本前言末尾的提供下載源碼、導(dǎo)圖和PPT,另外可在我的gitee下載課后練習(xí)題答案,包括課后練習(xí)題(除動(dòng)手練習(xí))參考答案和動(dòng)手練習(xí)參考答案。
參考資料
1、學(xué)習(xí)本書需要具備Java基礎(chǔ),如果您沒學(xué)過Java的話,可學(xué)習(xí)以下系列的Java教程《Java開發(fā)筆記》,或閱讀筆者的Java專著《好好學(xué)Java:從零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)》。
2、由于篇幅所限,本書只覆蓋了較為常見的Android開發(fā)技術(shù),其余的Android開發(fā)技術(shù)可參考以下的Android筆記《Android開發(fā)筆記》。
3、本書的技術(shù)實(shí)現(xiàn)采用的是Java編碼,若您想進(jìn)一步了解App開發(fā)中的Kotlin編程技術(shù),可閱讀以下系列的Kotlin教程《Kotlin入門教程》。
4、更多的App開發(fā)進(jìn)階內(nèi)容可參考這本書《Android App開發(fā)進(jìn)階與項(xiàng)目實(shí)戰(zhàn)》。
文字勘誤
下面對書中的筆誤之處進(jìn)行更正說明:
一、第一批勘誤記錄(以下的勘誤記錄在2023年1月的第二次印刷時(shí)均已修正)
1、第292頁的“11.2.3 ?跟蹤滑動(dòng)軌跡實(shí)現(xiàn)手寫簽名”
代碼注釋中的“// 設(shè)置畫筆的類型,STROK表示空心”,在STROK后面加個(gè)E,也就是改為“// 設(shè)置畫筆的類型,STROKE表示空心”。
2、第302頁的“11.4.1 ?上下滾動(dòng)與左右滑動(dòng)的沖突處理”
代碼里面的注釋文字“// 水平方向的滾動(dòng)”描述不夠完整,改為“// 橫軸方向的偏移大等于縱軸方向的偏移,則判定為水平方向的滾動(dòng)”。
3、第20章的“20.1.3 ?搭建穿透服務(wù)器”
該小節(jié)中間的“結(jié)合cygwin與coturn的安裝配置步驟說明”,步驟04的“然后打開turnserver.conf,補(bǔ)充以下幾行服務(wù)器的參數(shù)配置”后面要補(bǔ)充紅字部分的listening-ip,完整的參數(shù)配置舉例如下:
#監(jiān)聽端口
listening-port=3478
#內(nèi)網(wǎng)IP(可通過ipconfig /all查看)
listening-ip=192.168.1.5
#外網(wǎng)IP
external-ip=120.36.33.151
#用戶名和密碼
user=admin:123456
#域名
realm=stun.xxx.cn
4、附錄C
該小節(jié)第一段第五行的“開發(fā)入門代”指 改為“開發(fā)入門”代指。
5、附錄D
GNSS詞條后面的中文說明末尾補(bǔ)充“(俄羅斯)”,也就是改為“全球衛(wèi)星導(dǎo)航系統(tǒng)(俄羅斯)”。
二、第二批勘誤記錄(以下的勘誤記錄在2023年3月的第三次印刷時(shí)均已修正)
1、第125頁下到第126頁上的“6.1.3 ?更安全的數(shù)據(jù)倉庫”
往倉庫中保存數(shù)據(jù)和獲取數(shù)據(jù)的代碼例子要調(diào)換位置。也就是把這兩段代碼互相換成下面這樣:
前面把數(shù)據(jù)倉庫的初始化以及讀寫操作封裝在DatastoreUtil中,接下來通過該工具類即可方便地訪問數(shù)據(jù)倉庫了。往數(shù)據(jù)倉庫保存數(shù)據(jù)的代碼示例如下:
(完整代碼見chapter06\src\main\java\com\example\chapter06\DatastoreWriteActivity.java)
// 獲取數(shù)據(jù)倉庫工具的實(shí)例
DatastoreUtil datastore = DatastoreUtil.getInstance(this);
datastore.setStringValue("name", name); ?// 添加一個(gè)名叫name的字符串
// 添加一個(gè)名叫age的整數(shù)
datastore.setIntValue("age", Integer.parseInt(age));
// 添加一個(gè)名叫height的整數(shù)
datastore.setIntValue("height", Integer.parseInt(height));
// 添加一個(gè)名叫weight的雙精度數(shù)
datastore.setDoubleValue("weight", Double.parseDouble(weight));
// 添加一個(gè)名叫married的布爾值
datastore.setBooleanValue("married", isMarried);
datastore.setStringValue("update_time",?
? ? ? ? ? ? ? ? ?DateUtil.getNowDateTime("yyyy-MM-dd HH:mm:ss"));
從數(shù)據(jù)倉庫獲取數(shù)據(jù)的代碼示例如下:
(完整代碼見chapter06\src\main\java\com\example\chapter06\DatastoreReadActivity.java)
// 從數(shù)據(jù)倉庫中讀取信息
private void readDatastore() {
? ? // 獲取數(shù)據(jù)倉庫工具的實(shí)例
? ? DatastoreUtil datastore = DatastoreUtil.getInstance(this);
? ? String desc = "數(shù)據(jù)倉庫中保存的信息如下:";
? ? desc = String.format("%s\n %s為%s", desc, "姓名",
? ? ? ? ? ? datastore.getStringValue("name"));
? ? desc = String.format("%s\n %s為%d", desc, "年齡",
? ? ? ? ? ? datastore.getIntValue("age"));
? ? desc = String.format("%s\n %s為%d", desc, "身高",
? ? ? ? ? ? datastore.getIntValue("height"));
? ? desc = String.format("%s\n %s為%.2f", desc, "體重",
? ? ? ? ? ? datastore.getDoubleValue("weight"));
? ? desc = String.format("%s\n %s為%b", desc, "婚否",
? ? ? ? ? ? datastore.getBooleanValue("married"));
? ? desc = String.format("%s\n %s為%s", desc, "更新時(shí)間",
? ? ? ? ? ? datastore.getStringValue("update_time"));
? ? tv_data.setText(desc);
}
2、第584頁的“19.2.1 ?人臉檢測”
把圖19-18下面的兩行依賴庫配置
implementation 'com.huawei.hms:ml-computer-vision-faceverify:2.2.0.300'
implementation?
? ? ? ? 'com.huawei.hms:ml-computer-vision-faceverify-model:2.2.0.300'
改為下面幾行
implementation 'com.huawei.hms:ml-computer-vision-face:2.0.5.300'
implementation?
? ? 'com.huawei.hms:ml-computer-vision-face-emotion-model:2.0.5.300'
implementation?
? ? 'com.huawei.hms:ml-computer-vision-face-feature-model:2.0.5.300'
implementation?
? ? 'com.huawei.hms:ml-computer-vision-face-shape-point-model:2.0.5.300'
3、第586頁的“19.2.2 ?人臉比對”
該小節(jié)第二段之后補(bǔ)充下面的第三段紅字:
引入人臉比對功能需要修改模塊的build.gradle,往dependencies節(jié)點(diǎn)添加如下配置,表示導(dǎo)入指定版本的人臉比對庫(公共的agconnect插件和庫工程hmsml也要導(dǎo)入):
implementation 'com.huawei.hms:ml-computer-vision-faceverify:2.2.0.300'
implementation?
? ? ? ? 'com.huawei.hms:ml-computer-vision-faceverify-model:2.2.0.300'
以比對兩張人臉圖片為例,詳細(xì)的比對過程說明如下。
三、第三批勘誤記錄(以下的勘誤記錄在2023年9月的第四次印刷時(shí)均已修正)
1、第88頁的“4.3.4 ?定時(shí)管理器AlarmManager”
該小節(jié)的“3.設(shè)置定時(shí)器的播報(bào)規(guī)則”,下面代碼例子的第六行,要把“FLAG_UPDATE_CURRENT”改為“PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT”,因?yàn)閺腁ndroid12開始必須添加 FLAG_IMMUTABLE 或者 FLAG_MUTABLE,修改后的代碼例子如下所示:
// 發(fā)送鬧鐘廣播
private void sendAlarm() {
? ? Intent intent = new Intent(ALARM_ACTION); ?// 創(chuàng)建一個(gè)廣播事件的意圖
? ? // 創(chuàng)建一個(gè)用于廣播的延遲意圖
? ? PendingIntent pIntent = PendingIntent.getBroadcast(this, 0,
? ? ? ? ? ? intent, PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
? ? // 從系統(tǒng)服務(wù)中獲取鬧鐘管理器
? ? AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE);
? ? // 給當(dāng)前時(shí)間加上若干秒
? ? long delayTime = System.currentTimeMillis() + mDelay*1000;
? ? if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
? ? ? ? // 允許在空閑時(shí)發(fā)送廣播,Android 6.0之后新增的方法
? ? ? ? alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? delayTime, pIntent);
? ? } else {
? ? ? ? // 設(shè)置一次性鬧鐘,延遲若干秒后,攜帶延遲意圖發(fā)送鬧鐘廣播
? ? ? ? alarmMgr.set(AlarmManager.RTC_WAKEUP, delayTime, pIntent);
? ? }
}
2、第546頁的“18.1.1 ?系統(tǒng)自帶的語音引擎”
該小節(jié)最后一段前面補(bǔ)充以下的紅字說明(因?yàn)閺腁ndroid11開始文本轉(zhuǎn)語音功能需要添加額外的服務(wù)聲明):
從Android11開始,文本轉(zhuǎn)語音功能需要添加額外的服務(wù)聲明,也就是修改App模塊的AndroidManifest.xml,在manifest節(jié)點(diǎn)內(nèi)部增加下面幾行:
? ? <queries>
? ? ? ? <intent>
? ? ? ? ? ? <action android:name="android.intent.action.TTS_SERVICE" />
? ? ? ? </intent>
? ? </queries>
這里面的關(guān)鍵是怎么判斷每個(gè)語音引擎到底都支持哪幾種語言……
3、第590頁的“19.3.1 ?人像摳圖”
該小節(jié)第一段之后補(bǔ)充以下的紅字說明:
引入人像摳圖功能需要修改模塊的build.gradle,往dependencies節(jié)點(diǎn)添加如下配置,表示導(dǎo)入指定版本的人像摳圖庫(公共的agconnect插件和庫工程hmsml也要導(dǎo)入):
implementation 'com.huawei.hms:ml-computer-vision-segmentation:2.2.0.300'
implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:2.2.0.300'
根據(jù)上述的摳圖步驟,編寫具體的實(shí)現(xiàn)代碼示例如下:
?
代碼勘誤
下面對隨書源碼的疏漏之處進(jìn)行更正說明:
1、代碼注釋中的“// 設(shè)置畫筆的類型,STROK表示空心”,在STROK后面加個(gè)E,也就是改為“// 設(shè)置畫筆的類型,STROKE表示空心”。
2、chapter04模塊里的chapter04\src\main\java\com\example\chapter04\AlarmActivity.java,把sendAlarm()方法里面的“FLAG_UPDATE_CURRENT”改為“PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT”,避免在Android12以上機(jī)型運(yùn)行閃退,因?yàn)閺腁ndroid12開始,必須添加 FLAG_IMMUTABLE 或者 FLAG_MUTABLE。
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter04/src/main/java/com/example/chapter04/AlarmActivity.java
3、chapter14模塊里的chapter14\src\main\res\layout\item_video.xml
把com.google.android.exoplayer2.ui.PlayerView改為com.google.android.exoplayer2.ui.StyledPlayerView,避免實(shí)戰(zhàn)項(xiàng)目的短視頻頁面閃退。
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter14/src/main/res/layout/item_video.xml
4、chapter16模塊里chapter16\src\main\java\com\example\chapter16\SatelliteSphereActivity.java的initLocation方法,為了避免Android11以上無法獲取衛(wèi)星信息而注釋下面幾行代碼。
// ? ? ? ?if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// ? ? ? ? ? ?// 實(shí)測發(fā)現(xiàn)部分手機(jī)的android11系統(tǒng)使用衛(wèi)星定位會(huì)沒返回
// ? ? ? ? ? ?bestProvider = LocationManager.NETWORK_PROVIDER;
// ? ? ? ?}
完整代碼見下
https://gitee.com/aqi00/advanceapp/blob/main/location/src/main/java/com/example/location/SatelliteSphereActivity.java
5、chapter18模塊的chapter18/src/main/AndroidManifest.xml,在manifest節(jié)點(diǎn)下面增加補(bǔ)充下面幾行:
? ? <queries>
? ? ? ? <intent>
? ? ? ? ? ? <action android:name="android.intent.action.TTS_SERVICE" />
? ? ? ? </intent>
? ? </queries>
這是因?yàn)閺腁ndroid11開始,文本轉(zhuǎn)語音功能需要添加額外的服務(wù)聲明。
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter18/src/main/AndroidManifest.xml
6、chapter19模塊的chapter19/build.gradle,在dependencies節(jié)點(diǎn)下面補(bǔ)充下面幾行依賴庫配置:
? ? // 人臉檢測和笑臉捕捉需要
? ? implementation 'com.huawei.hms:ml-computer-vision-face:2.0.5.300'
? ? implementation 'com.huawei.hms:ml-computer-vision-face-emotion-model:2.0.5.300'
? ? implementation 'com.huawei.hms:ml-computer-vision-face-feature-model:2.0.5.300'
? ? implementation 'com.huawei.hms:ml-computer-vision-face-shape-point-model:2.0.5.300'
? ? // 人像摳圖需要
? ? implementation 'com.huawei.hms:ml-computer-vision-segmentation:2.2.0.300'
? ? implementation 'com.huawei.hms:ml-computer-vision-image-segmentation-body-model:2.2.0.300'
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter19/build.gradle
7、chapter19模塊的chapter19/src/main/java/com/example/chapter19/FaceDetectActivity.java,在saveFace方法內(nèi)部,把下面兩行
String path = String.format("%s/%s.jpg",
getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(), DateUtil.getNowDateTime());
改為下面兩行
String path = String.format("%s/%s.jpg",
? ? ? ? "/storage/emulated/0/DCIM/Camera", DateUtil.getNowDateTime());
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter19/src/main/java/com/example/chapter19/FaceDetectActivity.java
8、hmsml模塊的hmsml/src/main/java/com/example/hmsml/image/util/ImageUtils.java,在saveToAlbum方法內(nèi)部,把下面兩行
? ? File root = new File(Environment.getExternalStorageDirectory().getAbsoluteFile(), this.context.getPackageName());
? ? File dir = new File(root, "image");
改成下面這行
? ? File dir = new File("/storage/emulated/0/DCIM/Camera");
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/hmsml/src/main/java/com/example/hmsml/image/util/ImageUtils.java
9、hmsml模塊的hmsml/src/main/java/com/example/hmsml/face/transactor/LocalFaceTransactor.java,在saveImage方法末尾增加下面一行
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(path))));
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/hmsml/src/main/java/com/example/hmsml/face/transactor/LocalFaceTransactor.java
10、服務(wù)端源碼包的HttpServer/src/com/servlet/verifycode/GenerateCode.java
把下面四行
JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(fis);
BufferedImage image = decoder.decodeAsBufferedImage();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
encoder.encode(image);
改為以下兩行
BufferedImage buffer = ImageIO.read(fis);
ImageIO.write(buffer, "jpeg", os);
同時(shí)去掉代碼開頭的這幾個(gè)import語句“import com.sun.image.codec.jpeg.***”。
這是因?yàn)樵瓉淼拇a在部分jdk版本會(huì)提示編譯失敗,修改之后即可消除編譯錯(cuò)誤。
完整代碼見下
https://gitee.com/aqi00/net_server/blob/master/HttpServer/src/com/servlet/verifycode/GenerateCode.java
11、chapter17模塊的chapter17/src/main/java/com/example/chapter17/MainActivity.java,涉及到藍(lán)牙操作的活動(dòng)跳轉(zhuǎn),都要增加判斷:如果當(dāng)前系統(tǒng)版本大于等于Android 12,就要?jiǎng)討B(tài)申請以下權(quán)限:BLUETOOTH_SCAN、BLUETOOTH_ADVERTISE、BLUETOOTH_CONNECT
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter17/src/main/java/com/example/chapter17/MainActivity.java文章來源:http://www.zghlxwxcb.cn/news/detail-418028.html
12、chapter19模塊的chapter19/src/main/AndroidManifest.xml,增加READ_PHONE_STATE的權(quán)限聲明,也就是補(bǔ)充下列配置
? ? <!-- 獲取 device id 辨別設(shè)備,Android 12 掃碼服務(wù)需要 -->
? ? <uses-permission android:name="android.permission.READ_PHONE_STATE" />
同時(shí)chapter19/src/main/java/com/example/chapter19/MainActivity.java在跳轉(zhuǎn)到掃碼頁面HmsScanActivity之前,要增加判斷:如果當(dāng)前系統(tǒng)版本大于等于Android 12,就要?jiǎng)討B(tài)申請READ_PHONE_STATE權(quán)限。
完整代碼見下
https://gitee.com/aqi00/android3/blob/main/chapter19/src/main/AndroidManifest.xml
https://gitee.com/aqi00/android3/blob/main/chapter19/src/main/java/com/example/chapter19/MainActivity.java
?文章來源地址http://www.zghlxwxcb.cn/news/detail-418028.html
到了這里,關(guān)于《Android Studio開發(fā)實(shí)戰(zhàn) 從零基礎(chǔ)到App上線(第3版)》資源下載和內(nèi)容勘誤的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!