Android user login and data storage: complete practice from permission request to internal and external storage [Complete practical steps, external storage, internal storage]

Step 1: Login page layout

To implement the user login function in MainActivity, first create a layout file activity_main.xml containing input fields for username and password and login button.

<!-- activity_main.xml -->
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/editTextUsername"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="用户名" />

    <EditText
        android:id="@+id/editTextPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="密码"
        android:inputType="textPassword" />

    <Button
        android:id="@+id/buttonLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="登录" />

</LinearLayout>

achieve effect
Insert image description here

Step 2: Product list page layout

In Android Studio, right-click the project'sapp directory and select "New" > "Activity" > "Empty Activity".
Insert image description here

Layout file activity_product_list.xml is used to display the product list.

<!-- activity_product_list.xml -->
<ListView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/listViewProducts"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

achieve effect
Insert image description here

Then, load the product data in ProductListActivity.java and display it in ListView.

import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;

public class ProductListActivity extends AppCompatActivity {
    
    

    private ListView listViewProducts;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_product_list);

        listViewProducts = findViewById(R.id.listViewProducts);

        // 在这里获取商品数据,可以从网络或本地获取
        // 假设你有一个商品列表的字符串数组
        String[] products = {
    
    "商品1", "商品2", "商品3", "商品4"};

        // 使用ArrayAdapter将商品数据绑定到ListView
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
                android.R.layout.simple_list_item_1, products);
        listViewProducts.setAdapter(adapter);
    }
}

Step 3: Implement login functionality

Then handle the login logic in MainActivity.java and verify that the username and password are correct. After successfully logging in, jump to the product list page.

package com.leo.login_filestore;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    
    

    private EditText editTextUsername;
    private EditText editTextPassword;
    private Button buttonLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editTextUsername = findViewById(R.id.editTextUsername);
        editTextPassword = findViewById(R.id.editTextPassword);
        buttonLogin = findViewById(R.id.buttonLogin);

        buttonLogin.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                // 在这里验证用户名和密码是否正确
                String username = editTextUsername.getText().toString();
                String password = editTextPassword.getText().toString();

                if (isValidCredentials(username, password)) {
    
    
                    // 登录成功,跳转到商品列表页面
                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
                } else {
    
    
                    // 登录失败,显示错误消息
                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private boolean isValidCredentials(String username, String password) {
    
    
        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
        // 这里可以将用户名和密码写在代码中或从其他数据源获取

        // 用户名和密码硬编码在代码中,用于演示
        String validUsername = "user";
        String validPassword = "password";

        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
        return username.equals(validUsername) && password.equals(validPassword);
    }

}

achieve effect
user

Step 4: Request external storage permissions

To request external storage permissions, you need to add a permission statement in AndroidManifest.xml.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:ignore="WrongManifestParent" />

Insert image description here

Step 5: Write the SaveUtil class to save data to a file on external storage

Create a SaveUtil.java class to handle the logic of saving data to external storage.

Use Environment.getExternalStorageDirectory() to get the root directory of the external storage, then create a file and write the data to it. This will make your code more flexible since it dynamically gets the path to the external storage instead of hardcoding the path. Make sure you take care of permissions when using external storage.

package com.leo.login_filestore;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import android.os.Environment;

public class SaveUtil {
    
    
    public static boolean saveDataToExternalStorage(String filename, String data) {
    
    
        // 在这里实现数据保存到外部存储的逻辑
        // 注意要处理异常情况
        try {
    
    
            // 获取外部存储根目录
            File root = Environment.getExternalStorageDirectory();

            // 创建要保存的文件
            File file = new File(root, filename);

            // 创建文件输出流
            FileOutputStream fos = new FileOutputStream(file);

            // 写入数据
            fos.write(data.getBytes());

            // 关闭文件输出流
            fos.close();

            return true;
        } catch (IOException e) {
    
    
            e.printStackTrace();
            return false;
        }
    }
}

Step 6: Call the SaveUtil class in MainActivity to save the user name and password

After successful login, call the SaveUtil class to save the username and password to external storage. Here we use simulated data, which in reality should save passwords more securely.

Default directory for storage:/storage/emulated/0/你的文件

// 登录成功后
if (isValidCredentials(username, password)) {
    
    
    // 保存用户名和密码到外部存储
    boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);
    if (saved) {
    
    
        // 跳转到商品列表页面
        startActivity(new Intent(MainActivity.this, ProductListActivity.class));
    } else {
    
    
        // 处理保存失败的情况
    }
}

Step 7: Request permission to save code in MainActivity

also needs to request permission in MainActivity. Typically, this is requested dynamically at the app's runtime.
Complete code

package com.leo.login_filestore;

import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import android.Manifest;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    
    
    private static final int PERMISSION_REQUEST_CODE = 1;

    private EditText editTextUsername;
    private EditText editTextPassword;

    private  String username;
    private  String password;

    private Button buttonLogin;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editTextUsername = findViewById(R.id.editTextUsername);
        editTextPassword = findViewById(R.id.editTextPassword);
        buttonLogin = findViewById(R.id.buttonLogin);
        // 请求外部存储权限
        requestStoragePermission();

        buttonLogin.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    

                // 在这里验证用户名和密码是否正确
                username = editTextUsername.getText().toString();
                password = editTextPassword.getText().toString();

                if (isValidCredentials(username, password)) {
    
    
                    // 登录成功,跳转到商品列表页面
                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
                    saveDataToExternalStorage();
                } else {
    
    
                    // 登录失败,显示错误消息
                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
    private void requestStoragePermission() {
    
    

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
    
    
            // 请求权限
            ActivityCompat.requestPermissions(this,
                    new String[]{
    
    Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    PERMISSION_REQUEST_CODE);
        }
    }

    private void saveDataToExternalStorage() {
    
    
        System.out.println(username + "," + password);
        // 可以使用FileOutputStream等方式
        boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);

    }

    private boolean isValidCredentials(String username, String password) {
    
    
        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
        // 这里可以将用户名和密码写在代码中或从其他数据源获取

        // 用户名和密码硬编码在代码中,用于演示
        String validUsername = "user";
        String validPassword = "password";

        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
        return username.equals(validUsername) && password.equals(validPassword);
    }

}

Implementation effect
Please add image description
Content stored in the virtual machine file——/storage/emulated/0/credentials.txt
Insert image description here

Step 8: Try to log in automatically

Currently we have implemented the logic of saving usernames and passwords to external storage. Next, you need to modify MainActivity, try to read the user name and password in the credentials.txt file when starting the application, and implement automatic login.

private static final String CREDENTIALS_FILE = "credentials.txt";

@Override
protected void onCreate(Bundle savedInstanceState) {
    
    
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ...

    // 尝试自动登录
    tryAutoLogin();
}

private void tryAutoLogin() {
    
    
    String savedCredentials = readDataFromExternalStorage(CREDENTIALS_FILE);
    if (savedCredentials != null) {
    
    
        String[] parts = savedCredentials.split(",");
        if (parts.length == 2) {
    
    
            String savedUsername = parts[0];
            String savedPassword = parts[1];

            // 检查保存的用户名和密码是否与有效凭据匹配
            if (isValidCredentials(savedUsername, savedPassword)) {
    
    
                // 自动登录成功,跳转到商品列表页面
                startActivity(new Intent(MainActivity.this, ProductListActivity.class));
            }
        }
    }
}

private String readDataFromExternalStorage(String filename) {
    
    
    try {
    
    
        File root = Environment.getExternalStorageDirectory();
        File file = new File(root, filename);

        if (file.exists()) {
    
    
            FileInputStream fis = new FileInputStream(file);
            InputStreamReader isr = new InputStreamReader(fis);
            BufferedReader bufferedReader = new BufferedReader(isr);

            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
    
    
                sb.append(line);
            }

            bufferedReader.close();
            return sb.toString();
        }
    } catch (IOException e) {
    
    
        e.printStackTrace();
    }

    return null;
}

The above code calls the method in onCreate, which will try to read and save from the file username and password and check that they match valid credentials. If the match is successful, it will perform automatic login and jump to the product list page. tryAutoLogincredentials.txt

Please make sure to add appropriate permission declarations in AndroidManifest.xml and handle storage permissions correctly on Android 11 and above.

Achieve automatic login effect
Please add image description

Step 9: Use internal storage files and SharedPreferences to implement automatic login functionality

We useSharedPreferences to save and retrieve usernames and passwords. The tryAutoLogin method attempts to obtain the saved credentials from SharedPreferences and automatically logs the user in if the credentials exist and are valid.

Make sure to implement the display of the product list in ProductListActivity. This part of the code should remain unchanged.

code show as below:

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    
    

    private EditText editTextUsername;
    private EditText editTextPassword;
    private Button buttonLogin;
    private SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editTextUsername = findViewById(R.id.editTextUsername);
        editTextPassword = findViewById(R.id.editTextPassword);
        buttonLogin = findViewById(R.id.buttonLogin);

        sharedPreferences = getSharedPreferences("MyAppPrefs", MODE_PRIVATE);

        tryAutoLogin();

        buttonLogin.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                String username = editTextUsername.getText().toString();
                String password = editTextPassword.getText().toString();

                if (isValidCredentials(username, password)) {
    
    
                    // 登录成功,保存用户名和密码到SharedPreferences
                    saveCredentials(username, password);

                    // 跳转到商品列表页面
                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
                } else {
    
    
                    // 登录失败,显示错误消息
                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void tryAutoLogin() {
    
    
        String savedUsername = sharedPreferences.getString("username", "");
        String savedPassword = sharedPreferences.getString("password", "");

        if (!savedUsername.isEmpty() && !savedPassword.isEmpty()) {
    
    
            // 自动登录成功,跳转到商品列表页面
            startActivity(new Intent(MainActivity.this, ProductListActivity.class));
        }
    }

    private void saveCredentials(String username, String password) {
    
    
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("username", username);
        editor.putString("password", password);
        editor.apply();
    }

    private boolean isValidCredentials(String username, String password) {
    
    
        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
        // 这里可以将用户名和密码写在代码中或从其他数据源获取

        // 示例:用户名和密码硬编码在代码中,用于演示
        String validUsername = "user";
        String validPassword = "password";

        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
        return username.equals(validUsername) && password.equals(validPassword);
    }
}

MainActivity完整代码

package com.leo.login_filestore;
/** 使用内部存储文件和SharedPreferences实现自动登录功能 **/
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {
    
    

    private EditText editTextUsername;
    private EditText editTextPassword;
    private Button buttonLogin;
    private SharedPreferences sharedPreferences;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editTextUsername = findViewById(R.id.editTextUsername);
        editTextPassword = findViewById(R.id.editTextPassword);
        buttonLogin = findViewById(R.id.buttonLogin);

        sharedPreferences = getSharedPreferences("MyAppPrefs", MODE_PRIVATE);

        tryAutoLogin();

        buttonLogin.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                String username = editTextUsername.getText().toString();
                String password = editTextPassword.getText().toString();

                if (isValidCredentials(username, password)) {
    
    
                    // 登录成功,保存用户名和密码到SharedPreferences
                    saveCredentials(username, password);

                    // 跳转到商品列表页面
                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
                } else {
    
    
                    // 登录失败,显示错误消息
                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    private void tryAutoLogin() {
    
    
        String savedUsername = sharedPreferences.getString("username", "");
        String savedPassword = sharedPreferences.getString("password", "");

        if (!savedUsername.isEmpty() && !savedPassword.isEmpty()) {
    
    
            // 自动登录成功,跳转到商品列表页面
            startActivity(new Intent(MainActivity.this, ProductListActivity.class));
        }
    }

    private void saveCredentials(String username, String password) {
    
    
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString("username", username);
        editor.putString("password", password);
        editor.apply();
    }

    private boolean isValidCredentials(String username, String password) {
    
    
        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
        // 这里可以将用户名和密码写在代码中或从其他数据源获取

        // 示例:用户名和密码硬编码在代码中,用于演示
        String validUsername = "user";
        String validPassword = "password";

        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
        return username.equals(validUsername) && password.equals(validPassword);
    }
}


/** # 外部存储实现自动登录 **/
//
//import android.content.Intent;
//import android.content.pm.PackageManager;
//import android.os.Bundle;
//import android.os.Environment;
//import android.view.View;
//import android.widget.Button;
//import android.widget.EditText;
//
//import android.Manifest;
//
//import androidx.annotation.NonNull;
//import androidx.appcompat.app.AppCompatActivity;
//import androidx.core.app.ActivityCompat;
//import androidx.core.content.ContextCompat;
//import android.widget.Toast;
//
//import java.io.BufferedReader;
//import java.io.File;
//import java.io.FileInputStream;
//import java.io.IOException;
//import java.io.InputStreamReader;
//
//public class MainActivity extends AppCompatActivity {
    
    
//    private static final int PERMISSION_REQUEST_CODE = 1;
//    private static final String CREDENTIALS_FILE = "credentials.txt";
//
//
//    private EditText editTextUsername;
//    private EditText editTextPassword;
//
//    private  String username;
//    private  String password;
//
//    private Button buttonLogin;
//
//    @Override
//    protected void onCreate(Bundle savedInstanceState) {
    
    
//        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_main);
//
//        editTextUsername = findViewById(R.id.editTextUsername);
//        editTextPassword = findViewById(R.id.editTextPassword);
//        buttonLogin = findViewById(R.id.buttonLogin);
//        // 请求外部存储权限
//        requestStoragePermission();
//
//        tryAutoLogin();
//
//        buttonLogin.setOnClickListener(new View.OnClickListener() {
    
    
//            @Override
//            public void onClick(View v) {
    
    
//
//                // 在这里验证用户名和密码是否正确
//                username = editTextUsername.getText().toString();
//                password = editTextPassword.getText().toString();
//
//                if (isValidCredentials(username, password)) {
    
    
//                    // 登录成功,跳转到商品列表页面
//                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
//                    saveDataToExternalStorage();
//                } else {
    
    
//                    // 登录失败,显示错误消息
//                    Toast.makeText(MainActivity.this, "登录失败,用户名或密码不正确", Toast.LENGTH_SHORT).show();
//                }
//            }
//        });
//    }
//    private void requestStoragePermission() {
    
    
//
//        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
//                != PackageManager.PERMISSION_GRANTED) {
    
    
//            // 请求权限
//            ActivityCompat.requestPermissions(this,
//                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
//                    PERMISSION_REQUEST_CODE);
//        }
//    }
//
//    private void saveDataToExternalStorage() {
    
    
//        System.out.println(username + "," + password);
//        // 可以使用FileOutputStream等方式
//        boolean saved = SaveUtil.saveDataToExternalStorage("credentials.txt", username + "," + password);
//
//    }
//
//    private boolean isValidCredentials(String username, String password) {
    
    
//        // 在这里实现验证逻辑,比较输入的用户名和密码是否正确
//        // 这里可以将用户名和密码写在代码中或从其他数据源获取
//
//        // 用户名和密码硬编码在代码中,用于演示
//        String validUsername = "user";
//        String validPassword = "password";
//
//        // 比较输入的用户名和密码与有效的用户名和密码是否匹配
//        return username.equals(validUsername) && password.equals(validPassword);
//    }
//
//    private void tryAutoLogin() {
    
    
//        String savedCredentials = readDataFromExternalStorage(CREDENTIALS_FILE);
//        if (savedCredentials != null) {
    
    
//            String[] parts = savedCredentials.split(",");
//            if (parts.length == 2) {
    
    
//                String savedUsername = parts[0];
//                String savedPassword = parts[1];
//
//                // 检查保存的用户名和密码是否与有效凭据匹配
//                if (isValidCredentials(savedUsername, savedPassword)) {
    
    
//                    // 自动登录成功,跳转到商品列表页面
//                    startActivity(new Intent(MainActivity.this, ProductListActivity.class));
//                }
//            }
//        }
//    }
//
//    private String readDataFromExternalStorage(String filename) {
    
    
//        try {
    
    
//            File root = Environment.getExternalStorageDirectory();
//            File file = new File(root, filename);
//
//            if (file.exists()) {
    
    
//                FileInputStream fis = new FileInputStream(file);
//                InputStreamReader isr = new InputStreamReader(fis);
//                BufferedReader bufferedReader = new BufferedReader(isr);
//
//                StringBuilder sb = new StringBuilder();
//                String line;
//                while ((line = bufferedReader.readLine()) != null) {
    
    
//                    sb.append(line);
//                }
//
//                bufferedReader.close();
//                return sb.toString();
//            }
//        } catch (IOException e) {
    
    
//            e.printStackTrace();
//        }
//
//        return null;
//    }
//
//}

Guess you like

Origin blog.csdn.net/qq_22841387/article/details/133684854