版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第8章
APP的本地化CONTENTS目錄02
手機區域設置01
國際化與本地化03
未本地化的應用程序04
本地化的應用程序國際化與本地化01手機區域設置02未本地化的應用程序03本地化的應用程序04THEEND謝謝第9章
應用程序發布CONTENTS目錄02
為什么要為應用程序簽名01
應用程序發布的步驟03
Android的簽名策略04
生成簽名文件05
為應用程序簽名06
使用zipalign工具優化應用程序07
發布到GooglePlayStore應用程序發布的步驟01應用程序發布在完成對Android應用程序的開發和測試工作后,就可以將應用程序發布出去,供用戶使用了。Android應用程序在發布之前,需要完成一系列的工作。本章以第10章的實例GPSLocationInMap為例,簡單介紹Android應用程序發布過程中相關的一系列工作,包括應用程序發布的步驟、應用程序的簽名、版本定義等。
完成開發工作,在模擬器上測試運行。
將應用程序開發過程中的調試信息移除。
考慮為應用程序添加EULA(
EndUserLicenseAgreement)。
為應用程序添加自己的圖標,取代默認的Android圖標。
定義應用程序的版本。
為應用程序進行簽名。
如果應用程序使用了GoogleMapAPI,需要申請MapAPI密鑰。
在真機上測試運行。
測試完成后,發布到GooglePlayStore或者其他應用程序網站。發布步驟其中應用程序的版本由AndroidManifest.xml文件中的<Manifest>標簽指定。例如:<manifestxmlns:android="/apk/res/android"package="introduction.android.gpsLocationInMapDemo"android:versionCode="1"android:versionName="1.0">……</manifest>其中,android:versionCode為一個整數值,代表應用程序代碼的相對版本,也就是版本更新過多少次。該值每次更新的值都應該比前一次的大,以便于應用程序檢查應用程序是否需要升級,此處表示第一次更新;android:versionName為一個字符串值,代表應用程序的版本信息,需要顯示給用戶,此處表示1.0版本。為什么要為應用程序簽名023.2為什么要為應用程序簽名Android系統要求簽名機制,所有安裝在Android系統上的軟件,必須都經過簽名。與Symbian系統要求對安裝軟件進行簽名的目的不同,Android系統要求軟件簽名不是為了獲得軟件在Android系統上安裝的權限,而是為了用簽名辨別軟件的開發者。所有的Android應用程序都要求開發者使用一個證書來進行簽名。該證書的私鑰由應用程序的開發者所擁有,Android系統通過該證書來識別應用程序的開發者。只有使用同一個證書簽名的應用程序,才能被Android系統允許進行升級、覆蓋安裝等操作。使用不同簽名的兩個應用程序,即使其包名和類名完全相同,Android系統也不會允許其安裝在同一個目錄下。之前的章節中提到過,我們之前開發的應用程序,沒有經過我們的簽名,卻可以在模擬器上安裝并且運行,是因為在AndroidStudio上開發的App默認使用Android構建系統自動賦予的調試簽名(DebugSigning)。需要注意的是,使用調試簽名的應用程序,只能在模擬器上允許,而不能在真機上運行,也不能上傳到GooglePlay,在真機上運行的應用程序,必須使用正式的證書進行簽名。用于給應用程序簽名的證書不需要是權威機構發布的證書,開發者可以生成自己的簽名證書。Android建議的簽名證書的有效期一般要長于25年。Android系統只有在應用程序安裝時才會檢查證書的過期時間。若安裝時證書已經過期,則應用程序不能安裝。若在應用程序安裝后證書過期,則不會影響應用程序的正常運行,但是會導致該應用程序再也不能升級。為應用程序進行數字簽名的過程如下:
導出未簽名的應用程序。
獲取簽名文件。
為應用程序簽名。下面具體講解數字簽名的實現過程。Android的簽名策略03Android的簽名策略通常情況下,Android為所有的應用程序開發者推薦的簽名策略是所有的應用程序都應該使用同一個證書進行簽名,并且證書的有效期應該長于應用程序的生命周期。這樣做的原因有以下三點:應用程序升級。若開發者希望某應用程序可以無縫升級到新版本,則新舊版本應用程序必須使用同一個證書進行簽名,否則不能升級。如果使用的不是同一個證書簽名,則新的應用程序會被安裝到一個完全不同的目錄下,相當于安裝了一個新的應用程序,而舊的應用程序不能升級。應用程序模塊化。Android系統允許多個以同一個證書簽名的應用程序運行在同一個進程中,并將其看作是一個應用程序。每個應用程序可以以模塊化部署,在升級時可以獨立地升級其中的某一個模塊。允許代碼或者數據共享。Android提供了以簽名為基礎的權限機制,應用程序可以為以相同證書簽名的其他應用程序公開自己的功能,這樣就可以在相同簽名的應用程序之間共享代碼和數據。Android的簽名策略另外一個決定簽名策略的重要因素是如何設置簽名密鑰的有效期。如果開發者計劃升級應用程序,則應該確保簽名密鑰的有效期超過應用程序的生命周期。Android建議密鑰的有效期應該長于25年。一旦密鑰過期,其簽名的應用程序將再也無法升級。如果使用同一個密鑰為多個應用程序簽名,則密鑰的有效期應該長于其中任何一個應用程序的生命周期。如果開發者計劃將應用程序發布到AndroidMarket上,則密鑰的有效期應該超過2050年10月22日,以便保證應用程序可以無縫升級。生成簽名文件049.4.1使用AndroidStudio生成Android簽名證書的方式一般是使用AndroidStudio的相關功能生成簽名證書。
在AndroidStudio工程界面,選擇Build→GeneratedSignedAppBundleorAPK菜單選項,如圖9.1所示。
彈出如圖9.2所示的對話框,選擇APK選項,單擊Next按鈕之后彈出如圖9.3所示的對話框,之后單擊CreateNew按鈕,如果不是第一次生成也可以選擇已有Key路徑。圖9.1
選擇生成簽名APK圖9.2
選擇APK生成對話框圖9.3
APK生成信息對話框9.4.1使用AndroidStudio生成Android簽名證書的方式一般是使用AndroidStudio的相關功能生成簽名證書。
在新建keystroe的對話框上確定要保存的keystore文件的保存位置和名字,并確定對應的keystore文件的密碼。此處將keystroe文件保存為“H:\Android\myKeystore\myKeystore.jks”,密碼為“123456”,如圖9.4所示。其中Alias為密鑰的別名,Validity為密鑰的有效期,建議大于25年。所有內容填寫完畢后,單擊OK按鈕,AndroidStudio會在指定的keyStroepath路徑下生成秘鑰文件mykeystore.jks,如圖9.5所示。圖9.4
創建密鑰對話框圖9.5
生成的簽名文件9.4.2使用keytool工具
使用命令方式生成簽名文件的過程稍微復雜一點。使用的是keytool命令,該命令位于<JDK安裝目錄>/bin文件夾下。運行cmd命令,輸入“keytool–help”回車,會顯示keytool命令的一系列參數的用法,如圖9.6所示。圖9.6
keytool命令讀者可以自己查閱幫助,在此就不一一介紹了。Keytool.exe命令用于生成密鑰,并且把密鑰信息存放到keystore文件中。運行命令行“keytool-v-genkey-keystoree:\AndroidKey\mykeystore.keystore–aliasmykey-validity20000”其中參數意義如下:-v為顯示詳細輸出信息。-genkey為產生密鑰。-keystore<keystorefilename>.keystore指定生成keystore文件的文件名。-alias<keyfilename>指定密鑰的別名。-validity<days>指定該密鑰的有效期限,單位是天。該命令運行后出現密鑰生成向導,開發者根據要求填寫相應信息,即可生成密鑰,如圖9.7所示。具體步驟說明如下:輸入keystore密碼:(輸入密碼“123456”,未回顯)再次輸入新密碼:(輸入密碼“123456”,未回顯)您的名字與姓氏是什么?[Unknown]:LeeBo您的組織單位名稱是什么?[Unknown]:SIAS您的組織名稱是什么?[Unknown]:DEP您所在的城市或區域名稱是什么?[Unknown]:Shenyang您所在的州或省份名稱是什么?[Unknown]:Liaoning該單位的兩字母國家代碼是什么[Unknown]:cnCN=LeeBo,OU=SIAS,O=DEP,L=Shenyang,ST=Liaoning,C=cn正確嗎?[否]:y正在為以下對象生成1,024位DSA密鑰對和自簽名證書(SHA1withDSA)(有效期為20,000天):CN=LeeBo,OU=SIAS,O=DEP,L=Shenyang,ST=Liaoning,C=cn輸入<mykey>的主密碼(如果和keystore密碼相同,按回車):再次輸入新密碼:(輸入密碼,未回顯)[正在存儲e:\AndroidKey\mykeystore.keystore]至此,已生成開發者簽名證書,存儲在E:\AndroidKey\mykeystore.keystore文件中。開發者可以使用該密鑰對應用程序進行簽名。圖9.7
密鑰生成向導為應用程序簽名059.6.1使用AndroidStudio有了簽名文件后,就可以為應用程序簽名了。簽名的方式可以使用AndroidStudio自帶工具方式和命令方式兩種。通過AndroidStudio方式對應用程序進行簽名的過程非常簡單。在AndroidStudio工程中,選擇Build|GeneratedSignedAPK菜單選項,在彈出的對話框中選擇簽名要使用的秘鑰文件,然后單擊Next按鈕。此處在彈出keystore文件選擇對話框中選中Chooseexisting…單選按鈕,使用9.4.1節中生成的mykeystore.jks文件,如圖9.8所示,并輸入密碼“123456”。在出現的對話框中選擇要存放簽名APK的目標文件夾,并設置生成apk的方式是debug還是release。此處選擇release模式,并單擊Finish按鍵,如圖9.9所示。Gradle會依據之前設置的內容,在目標文件夾下生成簽名的apk文件,如圖9.10所示,簽名過程完成。圖9.8
“Keystoreselection”對話框圖9.9
Destinationandkey/certificatechecks界面圖9.10
生成的apk文件9.5.2使用jarsigner工具使用命令方式進行簽名,使用的是jarsigner命令,該命令和keytool命令一樣,被放置在<JDK的安裝目錄>\bin文件夾下。在cmd窗口中運行“jarsigner–help”,顯示該命令的各個參數的具體用法,如圖9.11所示。圖9.11
jarsigner命令假設有一個未簽名的apk文件為GPSLocationInMap.apk。運行cmd命令,將命令路徑設置到未簽名apk文件所在目錄,此處為“Q:\book\unsignedApp”。簽名的證書文件保存路徑為“e:/Androidkey/mykeystore.keystore”。使用jarsigner為GPSLocationInMap.apk文件簽名的命令為“jarsigner-verbose-keystoree:/Androidkey/mykeystore.keystoreGPSLocationInMapDemo.apkmykey”,其中:-verbose表示開啟詳細輸出。-keystore<keystorefilename>.keystore指定用于簽名的keystore文件的文件名。mykey表示用于簽名的密鑰的別名。運行結果如圖9.12所示。輸入密鑰庫的口令短語:(輸入“123456”)
正在添加:META-INF/MANIFEST.MF
正在添加:META-INF/MYKEY.SF
正在添加:META-INF/MYKEY.DSA
正在簽名:res/layout/main.xml
正在簽名:AndroidManifest.xml
正在簽名:resources.arsc
正在簽名:res/drawable-hdpi/ic_launcher.png
正在簽名:res/drawable-ldpi/ic_launcher.png
正在簽名:res/drawable-mdpi/ic_launcher.png
正在簽名:classes.dex至此,完成了對GPSLocationInMap.apk的簽名工作。圖9.12
使用jarsigner為GPSLocationInMap.apk文件簽名的運行結果使用zipalign工具優化應用程序06AndroidSDK包含一個名為zipalign的工具,存放在tools文件夾下。該工具能夠對打包的apk應用程序進行優化,將資源文件對齊到4字節邊界,以加快資源的讀取速度。使用zipalign工具優化過的應用程序,在運行時可以使Android與應用程序間的交互更加有效率,讓應用程序和整個系統運行得更快。因此簽名的應用程序在發布之前應該使用zipalign工具來得到優化后的版本。
使用ADT插件簽名的應用程序,Eclipse會自動使用zipalign工具進行優化,因此不需要我們人工干預。使用命令方式簽名的應用程序,需要使用zipalign工具優化。優化方法如下:運行cmd,切換到簽名的apk應用程序所在目錄,以Q:\book\unsignedApp\GPSLocationInMapDemo.apk文件為例,對其優化需運行如下命令:zipalign-v4GPSLocationInMapDemo.apkGPSLocationInMapDemo_aligned.apk其中-v表示開啟詳細輸出,4表示對齊字節的個數,必須為4才能起到優化效果。該命令運行結果如下:VerifyingalignmentofGPSLocationInMapDemo_aligned.apk(4)...50META-INF/MANIFEST.MF(OK-compressed)464META-INF/MYKEY.SF(OK-compressed)946META-INF/MYKEY.DSA(OK-compressed)1784res/layout/main.xml(OK-compressed)2275AndroidManifest.xml(OK-compressed)3076resources.arsc(OK)4476res/drawable-hdpi/ic_launcher.png(OK)8508res/drawable-ldpi/ic_launcher.png(OK)10108res/drawable-mdpi/ic_launcher.png(OK)12349classes.dex(OK-compressed)Verificationsuccessful運行效果如圖9.13所示。需要注意的是,該優化必須在簽名之后進行。若先進行優化再對apk文件進行簽名,會失去優化效果。圖9.13
zipalign優化發布到GooglePlayStore07完成對APK文件的簽名后,就可以將應用程序發布到Google公司提供的網絡發布平臺GooglePlayStore中了。GooglePlayStore的網址為/google-play-store。圖9.14
發布到GooglePlayStoreGooglePlayStore原名AndroidMarket(Android市場)。AndroidMarket是Google為Android設備開發的在線應用程序商店。Android手機在出廠時已經預裝了AndroidMarket,Android用戶可以通過AndroidMarket瀏覽和下載第三方開發者發布的Android應用程序,同時也可以將自己開發的應用程序發布到AndroidMarket上供其他用戶下載和使用。Google通過AndroidMarket將全球的Android用戶聯系在了一起,同時也為Android用戶提供了創業的平臺。隨著Android系統本身地位不斷攀升,占領了全球大部分智能手機市場的同時,AndroidMarket卻在被快速的邊緣化,于是Google在AndroidMarket中加入了電影,電子書和音樂(部分服務僅限于美國地區)等服務,豐富其功能,想讓其成為一個超級市場。北京時間2012年3月7日凌晨,Google公司將AndroidMarket正式更名為GooglePlayStore。此舉旨在讓消費者更加清楚地認識到Google提供的一系列廣泛內容,而不只是用于Android智能手機和平板電腦的應用,以便提升自身在電子內容銷售市場上的形象以及更好地與蘋果和亞馬遜競爭。對于Android開發者來說,在GooglePlayStore中注冊后,只要一次性支付25美元,便可成為GooglePlayStore的會員,進而可以在該平臺上發布自己的軟件,并可以通過GooglePlayStore提供的信息統計平臺查看到該軟件被下載、安裝、評級等相關信息。THEEND謝謝第10章
綜合實例:
圖書館管理系統本章是對本書知識點的綜合應用,包括GUI、數據存儲、短信應用等諸多內容。CONTENTS目錄02
系統注冊與登錄01
系統功能03
管理員功能04
讀者功能系統功能0110.1系統功能圖書館管理系統分為管理員和讀者兩種角色。管理員具有讀者管理、圖書管理、借閱管理和系統管理四個模塊。讀者管理負責對讀者信息的增刪改查;圖書管理用于對圖書信息的增刪改查;借閱管理負責借書和還書功能;系統設置用于設置系統超期期限和超期單位罰金。讀者具有圖書查詢和借書功能。
圖書館管理系統的功能模塊如圖10.1所示。圖書館管理系統管理員讀者圖書管理讀者管理借還管理系統管理查詢圖書借閱圖書借閱歷史圖10.1功能模塊設計系統注冊與登錄0210.2.1系統首頁其對應布局文件activity_main.xml代碼如下:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:orientation="vertical"android:padding="24dp"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_horizontal"android:background="#FAFAFA"><TextViewandroid:id="@+id/welcomeText"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/app_name"android:textSize="24sp"android:textStyle="bold"android:layout_marginBottom="16dp"android:textColor="#000000"/><!--插入圖片--><ImageViewandroid:layout_width="300dp"android:layout_height="300dp"android:src="@drawable/glxt"android:layout_marginBottom="16dp"/><Buttonandroid:id="@+id/btnLogin"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/login"android:layout_marginBottom="16dp"android:backgroundTint="#3F51B5"android:textColor="#FFFFFF"/><Buttonandroid:id="@+id/btnRegister"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/register"android:backgroundTint="#4CAF50"android:textColor="#FFFFFF"/></LinearLayout>圖10.2系統首頁MainActivity實現了跳轉注冊頁和登錄頁的功能,并且啟動了定時提醒任務。代碼如下:packageroduction.librarymanagement;importandroid.Manifest;importandroid.content.Intent;importandroid.os.Bundle;importandroid.widget.Button;importandroidx.appcompat.app.AppCompatActivity;importandroidx.core.app.ActivityCompat;publicclassMainActivityextendsAppCompatActivity{privateButtonbtnLogin,btnRegister;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//DBHelperdbHelper=newDBHelper(this);//SQLiteDatabasedb=dbHelper.getWritableDatabase();//dbHelper.onUpgrade(db,1,2);btnLogin=findViewById(R.id.btnLogin);btnRegister=findViewById(R.id.btnRegister);btnLogin.setOnClickListener(v->{Intentintent=newIntent(MainActivity.this,LoginActivity.class);startActivity(intent);});btnRegister.setOnClickListener(v->{Intentintent=newIntent(MainActivity.this,RegisterActivity.class);startActivity(intent);});//每日發送超期提醒信息ReminderScheduler.scheduleDailyReminder(this);//初始化提醒服務ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.SEND_SMS},1001);}}其中DBHelperdbHelper=newDBHelper(this);SQLiteDatabasedb=dbHelper.getWritableDatabase();dbHelper.onUpgrade(db,1,2);這三行代碼用于首次運行時初始化數據庫,并寫入基礎測試數據。ReminderScheduler.scheduleDailyReminder(this);//初始化提醒服務ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.SEND_SMS},1001);用于啟動每日的定時任務,并且申請發送短信的權限。10.2.2注冊功能登錄界面如圖10.4所示。“記住我”的功能是通過SharedPreferences實現了記錄上次登錄的人的信息。圖10.4登錄界面其布局文件activity_login.xml代碼如下:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="24dp"><EditTextandroid:id="@+id/edtEmail"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="@string/email"/><EditTextandroid:id="@+id/edtPassword"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="@string/password"android:inputType="textPassword"/><CheckBoxandroid:id="@+id/chkRemember"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/remember_me"/><Buttonandroid:id="@+id/btnLogin"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@string/login"/></LinearLayout>LoginActivity.java代碼如下:packageroduction.librarymanagement;importandroid.content.Intent;importandroid.content.SharedPreferences;importandroid.os.Bundle;importandroid.widget.Button;importandroid.widget.CheckBox;importandroid.widget.EditText;importandroid.widget.Toast;importandroidx.appcompat.app.AppCompatActivity;publicclassLoginActivityextendsAppCompatActivity{privateEditTextedtEmail,edtPassword;privateCheckBoxchkRemember;privateButtonbtnLogin;privateDBHelperdbHelper;privateSharedPreferencessharedPreferences;privatestaticfinalStringPREFS_NAME="LoginPrefs";@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);edtEmail=findViewById(R.id.edtEmail);edtPassword=findViewById(R.id.edtPassword);chkRemember=findViewById(R.id.chkRemember);btnLogin=findViewById(R.id.btnLogin);dbHelper=newDBHelper(this);sharedPreferences=getSharedPreferences(PREFS_NAME,MODE_PRIVATE);loadSavedCredentials();btnLogin.setOnClickListener(v->{Stringemail=edtEmail.getText().toString();Stringpassword=edtPassword.getText().toString();intuserId=dbHelper.validateUser(email,password);if(userId!=-1){if(chkRemember.isChecked()){saveCredentials(email,password);}else{clearCredentials();}Stringrole=dbHelper.getUserRole(userId);Intentintent;if("admin".equals(role)){intent=newIntent(LoginActivity.this,AdminDashboardActivity.class);}else{intent=newIntent(LoginActivity.this,BorrowActivity.class);}intent.putExtra("student_id",userId);startActivity(intent);finish();}else{Toast.makeText(this,"登錄失敗:賬號或密碼錯誤",Toast.LENGTH_SHORT).show();}});}privatevoidsaveCredentials(Stringemail,Stringpassword){SharedPreferences.Editoreditor=sharedPreferences.edit();editor.putString("email",email);editor.putString("password",password);editor.putBoolean("remember",true);editor.apply();}privatevoidloadSavedCredentials(){booleanremember=sharedPreferences.getBoolean("remember",false);if(remember){edtEmail.setText(sharedPreferences.getString("email",""));edtPassword.setText(sharedPreferences.getString("password",""));chkRemember.setChecked(true);}}privatevoidclearCredentials(){sharedPreferences.edit().clear().apply();}}10.2.4數據庫操作類DBHelper圖書館管理系統中Sqlite數據庫repairdb中創建了三個數據表,分別是Users、Books和BorrowRecords表。操作數據庫是基于DBHelper這個類,實現了數據庫的創建、測試數據插入,以及數據表的增刪改查功能。DBHelper.java的代碼如下:packageroduction.librarymanagement;importandroid.content.ContentValues;importandroid.content.Context;importandroid.database.Cursor;importandroid.database.sqlite.SQLiteDatabase;importandroid.database.sqlite.SQLiteOpenHelper;importjava.text.SimpleDateFormat;importjava.util.Calendar;importjava.util.Locale;publicclassDBHelperextendsSQLiteOpenHelper{privatestaticfinalStringDB_NAME="library.db";privatestaticfinalintDB_VERSION=1;publicDBHelper(Contextcontext){super(context,DB_NAME,null,DB_VERSION);}@OverridepublicvoidonCreate(SQLiteDatabasedb){//db.execSQL("CREATETABLEUsers(idINTEGERPRIMARYKEYAUTOINCREMENT,nameTEXT,roleTEXT,emailTEXTUNIQUE,passwordTEXT,phoneTEXTUNIQUE)");//db.execSQL("CREATETABLEBooks(idINTEGERPRIMARYKEYAUTOINCREMENT,titleTEXT,authorTEXT,available_copiesINTEGER,total_copiesINTEGER)");//db.execSQL("CREATETABLEBorrowRecords(idINTEGERPRIMARYKEYAUTOINCREMENT,user_idINTEGER,book_idINTEGER,borrow_dateTEXT,due_dateTEXT,return_dateTEXT,fineINTEGER)");//////SampleUsers//db.execSQL("INSERTINTOUsers(name,role,email,password,phone)VALUES('AdminUser','admin','admin@','admin123',)");//db.execSQL("INSERTINTOUsers(name,role,email,password,phone)VALUES('StudentUser','student','student@','student123',)");//db.execSQL("INSERTINTOUsers(name,role,email,password,phone)VALUES('a1','student','a1@','1234',)");//db.execSQL("INSERTINTOUsers(name,role,email,password,phone)VALUES('a2','student','a2@','1234',)");//////SampleBooks//db.execSQL("INSERTINTOBooks(title,author,available_copies,total_copies)VALUES('JavaProgramming','JohnDoe',5,5)");//db.execSQL("INSERTINTOBooks(title,author,available_copies,total_copies)VALUES('AndroidDevelopment','JaneSmith',3,3)");}privatevoidinsertTestData(SQLiteDatabasedb){//插入20條圖書數據for(inti=1;i<=20;i++){ContentValuesbook=newContentValues();book.put("title","測試圖書"+i);book.put("author","作者"+((char)('A'+i%5)));book.put("available_copies",5+(i%3));db.insert("Books",null,book);}//插入20條借書記錄(假設用戶ID1-3之間輪流借閱)SimpleDateFormatsdf=newSimpleDateFormat("yyyy-MM-dd",Locale.getDefault());Calendarcalendar=Calendar.getInstance();for(inti=1;i<=20;i++){ContentValuesborrow=newContentValues();borrow.put("user_id",(i%3)+1);borrow.put("book_id",i);calendar.set(2024,Calendar.JANUARY,i);borrow.put("borrow_date",sdf.format(calendar.getTime()));calendar.add(Calendar.DAY_OF_MONTH,14);borrow.put("due_date",sdf.format(calendar.getTime()));borrow.put("fine",0);if(i%4==0){calendar.add(Calendar.DAY_OF_MONTH,1);borrow.put("return_date",sdf.format(calendar.getTime()));}else{borrow.putNull("return_date");}db.insert("BorrowRecords",null,borrow);}}@OverridepublicvoidonUpgrade(SQLiteDatabasedb,intoldVersion,intnewVersion){db=this.getWritableDatabase();db.execSQL("DROPTABLEIFEXISTSUsers");db.execSQL("DROPTABLEIFEXISTSBooks");db.execSQL("DROPTABLEIFEXISTSBorrowRecords");onCreate(db);}//驗證用戶是否存在并返回其IDpublicintvalidateUser(Stringemail,Stringpassword){SQLiteDatabasedb=this.getReadableDatabase();Cursorcursor=db.rawQuery("SELECTidFROMUsersWHEREemail=?ANDpassword=?",newString[]{email,password});if(cursor.moveToFirst()){intuserId=cursor.getInt(0);cursor.close();returnuserId;}cursor.close();return-1;//用戶不存在或密碼錯誤}//獲取用戶的角色publicStringgetUserRole(intuserId){SQLiteDatabasedb=this.getReadableDatabase();Cursorcursor=db.rawQuery("SELECTroleFROMUsersWHEREid=?",newString[]{String.valueOf(userId)});if(cursor.moveToFirst()){Stringrole=cursor.getString(0);cursor.close();returnrole;}cursor.close();returnnull;}}管理員功能0310.3.1功能界面其布局文件activity_admin_dashboard.xml代碼如下:<?xmlversion="1.0"encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayoutxmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"><!--2×2網格容器--><androidx.gridlayout.widget.GridLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"app:columnCount="2"app:rowCount="2"app:layout_constraintTop_toTopOf="parent"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintEnd_toEndOf="parent"><!--1管理圖書--><ImageButtonandroid:id="@+id/manageBooksBtn"android:layout_width="150dp"android:layout_height="150dp"android:src="@drawable/tsgl"android:scaleType="fitCenter"android:adjustViewBounds="true"android:background="?attr/selectableItemBackgroundBorderless"android:contentDescription="@string/manage_books"android:layout_margin="8dp"/>圖10.5系統功能界面<!--2管理學生--><ImageButtonandroid:id="@+id/manageStudentsBtn"android:layout_width="150dp"android:layout_height="150dp"android:src="@drawable/dzgl"android:scaleType="fitCenter"android:adjustViewBounds="true"android:background="?attr/selectableItemBackgroundBorderless"android:contentDescription="@string/manage_students"android:layout_margin="8dp"/><!--3借閱管理--><ImageButtonandroid:id="@+id/returnBookBtn"android:layout_width="150dp"android:layout_height="150dp"android:src="@drawable/jygl"android:scaleType="fitCenter"android:adjustViewBounds="true"android:background="?attr/selectableItemBackgroundBorderless"android:contentDescription="@string/borrow_book"android:layout_margin="8dp"/><!--3系統設置--><ImageButtonandroid:id="@+id/borrowBookBtn"android:layout_width="150dp"android:layout_height="150dp"android:src="@drawable/xtsz"android:scaleType="fitCenter"android:adjustViewBounds="true"android:background="?attr/selectableItemBackgroundBorderless"android:contentDescription="@string/return_book"android:layout_margin="8dp"/></androidx.gridlayout.widget.GridLayout></androidx.constraintlayout.widget.ConstraintLayout>AdminDashboardActivity.java代碼如下:packageroduction.librarymanagement;importandroid.content.Intent;importandroid.os.Bundle;importandroidx.appcompat.app.AppCompatActivity;publicclassAdminDashboardActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_admin_dashboard);findViewById(R.id.manageBooksBtn).setOnClickListener(v->startActivity(newIntent(this,ManageBooksActivity.class)));findViewById(R.id.manageStudentsBtn).setOnClickListener(v->startActivity(newIntent(this,ManageStudentsActivity.class)));findViewById(R.id.borrowBookBtn).setOnClickListener(v->startActivity(newIntent(this,AdminProfileActivity.class)));findViewById(R.id.returnBookBtn).setOnClickListener(v->startActivity(newIntent(this,ReturnActivity.class)));}}10.3.2圖書管理圖10.6系統功能界面管理員的圖書管理界面如圖10.6所示。長按列表中的某一項,會彈出上下文菜單,如圖10.7所示,實現對某一本圖書的修改和刪除操作。圖10.7圖書管理上下文菜單其布局文件activity_borrow_books.xml代碼如下:<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"xmlns:app="/apk/res-auto"android:orientation="vertical"android:padding="16dp"><Buttonandroid:id="@+id/addBookBtn"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@string/add_book"/><ListViewandroid:id="@+id/listBooks"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"/><com.google.android.material.bottomnavigation.BottomNavigationViewandroid:id="@+id/bottomNavigationView1"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="?android:attr/windowBackground"app:menu="@menu/admin_bottom_nav_menu"android:layout_gravity="bottom"/></LinearLayout>ManageBooksActivity.java代碼如下:packageroduction.librarymanagement;importandroid.app.AlertDialog;importandroid.content.ContentValues;importandroid.database.Cursor;importandroid.database.sqlite.SQLiteDatabase;importandroid.os.Bundle;importandroid.view.View;importandroid.widget.ArrayAdapter;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.ListView;importandroidx.appcompat.app.AppCompatActivity;importcom.google.android.material.bottomnavigation.BottomNavigationView;importjava.util.ArrayList;importjava.util.List;publicclassManageBooksActivityextendsAppCompatActivity{privateListViewlistView;privateArrayAdapter<Book>adapter;privateList<Book>books;privateDBHelperdbHelper;@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_manage_books);dbHelper=newDBHelper(this);listView=findViewById(R.id.listBooks);books=loadBooksFromDatabase();adapter=newBookAdapter(this,books);listView.setAdapter(adapter);//Long-clicktoeditordeletebooklistView.setOnItemLongClickListener((parent,view,position,id)->{Bookbook=
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 會展策劃與管理專業培訓考核大綱
- 高分子防水卷材生產工誠信道德能力考核試卷含答案
- 鑿巖工安全素養評優考核試卷含答案
- 硅片研磨工QC管理評優考核試卷含答案
- 電池配料工QC管理測試考核試卷含答案
- 2026中儲糧儲運限公司公開招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 2026東莞松山湖科學城發展集團限公司招聘易考易錯模擬試題(共500題)試卷后附參考答案
- 油墨制造工技能評估競賽考核試卷含答案
- 飲料灌裝工決策判斷競賽考核試卷含答案
- 2026下半年貴州安順關嶺縣事業單位招聘170人易考易錯模擬試題(共500題)試卷后附參考答案
- 【英語】江蘇省蘇錫常鎮2025屆高三下學期二模試題(解析版)
- 2025四川成都新都投資集團有限公司招聘23人筆試參考題庫附帶答案詳解(10套)
- 病房改造及能力提升項目建設方案
- 貝殼培訓考試試題及答案
- 2025新高考數學核心母題400道(教師版)
- 第六屆全國農業行業職業技能大賽(農業經理人賽項)理論參考試題庫-下(多選、判斷題)
- DB45T 2871-2024 既有住宅加裝電梯安全技術規范
- 《電力建設工程施工安全管理導則》(NB∕T 10096-2018)
- 字母認主協議書(2篇)
- 2024年城市軌道交通信號工(中級)技能鑒定考試題庫-下(多選、判斷題)
- 完整版交管12123駕照學法考試題庫加答案
評論
0/150
提交評論