直接上代碼:(超詳細)
1. 首先是AndroidManifest.xml文件

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tool="http://schemas.android.com/tools" package="com.example.express_delivery"> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" /> <!-- 訪問網絡,進行地圖相關業務數據請求,包括地圖數據,路線規划,POI檢索等 --> <uses-permission android:name="android.permission.INTERNET" /> <!-- 獲取網絡狀態,根據網絡狀態切換進行數據請求網絡轉換 --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 讀取外置存儲。如果開發者使用了so動態加載功能並且把so文件放在了外置存儲區域,則需要申請該權限,否則不需要 --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 寫外置存儲。如果開發者使用了離線地圖,並且數據寫在外置存儲區域,則需要申請該權限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 這個權限用於進行網絡定位 --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 這個權限用於訪問GPS定位 --> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /> <!-- 允許讀取手機的狀態 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.INTERNET android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <!-- 用於獲取wifi的獲取權限,wifi信息會用來進行網絡定位 --> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 用於申請調用A-GPS模塊 --> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <!-- 用於申請獲取藍牙信息進行室內定位 --> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <application android:name=".DemoApplication" android:allowBackup="true" android:icon="@drawable/launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tool:ignore="LockedOrientationActivity"> <activity android:name=".activity.SettingActivity"></activity> <activity android:name=".login_register.MyRegisterActivity" /> <activity android:name=".login_register.LoginActivity" /> <activity android:name=".NotLoginActivity" /> <activity android:name=".select_city.City_SelectActivity" /> <activity android:name=".FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".RegisterActivity" /> <activity android:name=".SplashActivity" android:screenOrientation="portrait" /> <activity android:name=".Personal_PageActivity" /> <activity android:name=".bring.Delivery_help_bring" /> <activity android:name=".purchase.Delivery_help_purchase" /> <activity android:name=".ReverseGeoCodeDemo" /> <activity android:name=".GeoCoderDemo" /> <activity android:name=".TestActivity" /> <activity android:name=".SearchDemoActivity" /> <activity android:name=".MarkDemoActivity" /> <activity android:name=".SearchCityActivity" /> <meta-data android:name="com.baidu.lbsapi.API_KEY" android:value="weLEDW6SWoTAOXUzhA6QvQzl6Cbt3YY4" /> <meta-data android:name="com.amap.api.v2.apikey" android:value="d1c7a4f1729f99b28c5229503ed48560" /> <service android:name="com.amap.api.location.APSService" /> <activity android:name=".MainActivity"> <!-- <intent-filter> --> <!-- <action android:name="android.intent.action.MAIN" /> --> <!-- <category android:name="android.intent.category.LAUNCHER" /> --> <!-- </intent-filter> --> </activity> <activity android:name="com.mob.tools.MobUIShell" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:windowSoftInputMode="stateHidden|adjustResize" /> <service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" /> </application> </manifest>
大家不用看那么多,有這么兩個注意的:
(1)有一句 android:name=".DemoApplication"(我寫了一個類,名為DemoApplication,繼承的是Application)
<application android:name=".DemoApplication" android:allowBackup="true" android:icon="@drawable/launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" tool:ignore="LockedOrientationActivity">
意思就是繼承Application,來實現數據共享,大家可以參考這個
DemoApplication.java

package com.example.express_delivery; import android.app.Application; import com.baidu.mapapi.CoordType; import com.baidu.mapapi.SDKInitializer; import com.blankj.utilcode.util.Utils; import com.mob.MobSDK; public class DemoApplication extends Application { @Override public void onCreate() { super.onCreate(); //在使用SDK各組件之前初始化context信息,傳入ApplicationContext SDKInitializer.initialize(this); //自4.3.0起,百度地圖SDK所有接口均支持百度坐標和國測局坐標,用此方法設置您使用的坐標類型. //包括BD09LL和GCJ02兩種坐標,默認是BD09LL坐標。 SDKInitializer.setCoordType(CoordType.BD09LL); MobSDK.init(this,"30640c6cc0e96", "195c8c7927621ee6651c0c2d3f5eb26d"); Utils.init(this); } }
(2)以及在其中一個activity下有這么個標簽,<intent-filter>
<activity android:name=".FirstActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
代表他是第一啟動項
FirstActivity.java

package com.example.express_delivery; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.widget.Button; import com.example.express_delivery.login_register.MyRegisterActivity; import com.example.express_delivery.utils.UserUtils; public class FirstActivity extends AppCompatActivity { private Button btn_tomain; private Handler handler; private static final long DELAY = 2000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first); //去掉標題欄 if (getSupportActionBar() != null){ getSupportActionBar().hide(); } final boolean isLogin= UserUtils.validateUserLogin(this); //等待2秒后自動跳轉到 對應的Activity(相當於是閃屏頁) handler = new Handler(); handler.postDelayed(new Runnable() { @Override public void run() { if (isLogin){ toMain(); }else { toLogin(); } } }, DELAY); } /** *跳轉到主界面 * */ private void toLogin(){ Intent intent=new Intent(this,MyRegisterActivity.class); startActivity(intent); finish(); } private void toMain(){ Intent intent=new Intent(this,MainActivity.class); startActivity(intent); finish(); } }
2. 這里就不寫是怎樣注冊的了,因為里邊沒有涉及到,我會再起一篇寫注冊登錄的
LoginActivity.java

package com.example.express_delivery.login_register; import androidx.appcompat.app.AppCompatActivity; import android.content.Intent; import android.os.Bundle; import android.text.TextUtils; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; import com.example.express_delivery.MainActivity; import com.example.express_delivery.Personal_PageActivity; import com.example.express_delivery.R; import com.example.express_delivery.utils.UserUtils; import java.util.ArrayList; public class LoginActivity extends AppCompatActivity implements View.OnClickListener{ private TextView tv_register,tv_login_forget_psw; private DBOpenHelper mDBOpenHelper; private EditText et_login_phone,et_login_password; private Button btn_login; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_login); if (getSupportActionBar() != null){ getSupportActionBar().hide(); } initView(); mDBOpenHelper = new DBOpenHelper(this); onclick(); btn_login.setOnClickListener(this); } private void initView() { tv_register = findViewById(R.id.tv_register); btn_login = findViewById(R.id.btn_login); et_login_phone = findViewById(R.id.et_login_phone); et_login_password = findViewById(R.id.et_login_password); tv_login_forget_psw = findViewById(R.id.tv_login_forget_psw); } private void onclick() { tv_register.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(LoginActivity.this, MyRegisterActivity.class); startActivity(intent); finish(); } }); } public void onClick(View view){ switch (view.getId()) { case R.id.btn_login: String name = et_login_phone.getText().toString().trim(); String password = et_login_password.getText().toString().trim(); if (!UserUtils.vaLidateLogin(this, name)) { return; } if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(password)) { ArrayList<User> data = mDBOpenHelper.getAllData(); boolean match = false; for (int i = 0; i < data.size(); i++) { User user = data.get(i); if (name.equals(user.getPhone()) && password.equals(user.getPassword())) { match = true; break; } else { match = false; } } if (match) { Toast.makeText(this, "登錄成功", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(this, MainActivity.class); startActivity(intent); finish();//銷毀此Activity } else { Toast.makeText(this, "用戶名或密碼不正確,請重新輸入", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(this, "請輸入你的用戶名或密碼", Toast.LENGTH_SHORT).show(); } break; } } }
其中大家注意到這幾行的判斷代碼,(其余的是數據庫的校驗)
String name = et_login_phone.getText().toString().trim(); String password = et_login_password.getText().toString().trim(); if (!UserUtils.vaLidateLogin(this, name)) { return; }
UserUtils.java

package com.example.express_delivery.utils; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.text.TextUtils; import android.widget.Toast; import com.example.express_delivery.login_register.LoginActivity; import com.example.express_delivery.login_register.UserHelper; public class UserUtils { public static boolean vaLidateLogin(Context context, String phone) { /** * 判斷用戶當前手機號是否已經被注冊 * 用戶輸入的手機號和密碼是否匹配 */ //保存用戶登錄標記 boolean isSave = saveUser(context,phone); if (!isSave){ Toast.makeText(context, "系統錯誤,請稍后重試", Toast.LENGTH_SHORT).show(); return false; } //保存用戶登錄標記,在全局單類例之中 UserHelper.getInstance().setPhone(phone); return true; } public static boolean saveUser (Context context, String phone) { SharedPreferences sp = context.getSharedPreferences(SPConstants.SP_NAME_USER, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString(SPConstants.SP_KEY_PHONE, phone); boolean result = editor.commit(); return result; } public static boolean validateUserLogin(Context context){ return isLoginUser(context); } /** * 驗證是否存在已登錄用戶 */ public static boolean isLoginUser (Context context) { boolean result = false; SharedPreferences sp = context.getSharedPreferences(SPConstants.SP_NAME_USER, Context.MODE_PRIVATE); String phone = sp.getString(SPConstants.SP_KEY_PHONE, ""); if (!TextUtils.isEmpty(phone)) { result = true; UserHelper.getInstance().setPhone(phone); } return result; } public static void logout (Context context) { // 刪除sp保存的用戶標記 boolean isRemove = removeUser(context); if (!isRemove) { Toast.makeText(context, "系統錯誤,請稍后重試", Toast.LENGTH_SHORT).show(); return; } Intent intent = new Intent(context, LoginActivity.class); // 添加intent標志符,清理task棧,並且新生成一個task棧 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } /** * 刪除用戶標記 */ public static boolean removeUser (Context context) { SharedPreferences sp = context.getSharedPreferences(SPConstants.SP_NAME_USER, Context.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.remove(SPConstants.SP_KEY_PHONE); boolean result = editor.commit(); return result; } }
SPConstants.java
package com.example.express_delivery.utils; public class SPConstants { public static final String SP_NAME_USER = "user"; public static final String SP_KEY_PHONE = "phone"; }
UserHelper.java

package com.example.express_delivery.login_register; /** * 1、用戶登錄 * 1、當用戶登錄時,利用SharedPreferences 保存登錄用戶的用戶標記(手機號碼) * 2、利用全局單例類UserHelper保存登錄用戶信息 * 1、用戶登錄之后 * 2、用戶打開應用程序,檢測SharedPreferences中是否存在登錄用戶標記 * ,如果存在則為UserHelp進行賦值,並且進入主頁。如果不存在,則進入登錄頁面 * 2、用戶退出 * 1、刪除掉SharedPreferences保存的用戶標記,退出到登錄頁面。 */ public class UserHelper { private static UserHelper instance; private UserHelper () {}; public static UserHelper getInstance() { if (instance == null) { synchronized (UserHelper.class) { if (instance == null) { instance = new UserHelper(); } } } return instance; } private String phone; public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } }
到這里代碼就放完了,如果有缺,大家可以留言評論,我會及時看到回復的(xml的布局文件沒有放,我在注冊登錄篇會放)