Android provides multiple storage options to manage data efficiently based on different use cases. Understanding these storage types is crucial for building apps that handle data securely and efficiently. This guide will explore the various storage types in Android, along with examples to demonstrate their usage.

Internal Storage

What is it?

Internal storage is private to the app. Files saved here are secure and inaccessible by other apps. When the app is uninstalled, the files stored in internal storage are automatically deleted.

Use Cases:

  • Storing sensitive information like user credentials.
  • Caching data that needs to persist across sessions.

// Saving a file to internal storage
String filename = “myfile.txt”;
String fileContents = “Hello, World!”;
FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE);
fos.write(fileContents.getBytes());
fos.close();

// Reading the file from internal storage
FileInputStream fis = openFileInput(filename);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader bufferedReader = new BufferedReader(isr);
StringBuilder sb = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
String fileContent = sb.toString();

External Storage

What is it?

External storage is accessible to both the user and other apps. It’s typically used for storing media files and documents that users expect to access outside the app. External storage can be either removable (like an SD card) or non-removable (like internal shared storage).

Use Cases:

  • Saving media files (images, videos, audio) that should be accessible to the user outside the app.
  • Storing documents or large datasets.

// Checking if external storage is available
boolean isExternalStorageWritable = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

// Saving a file to external storage
if (isExternalStorageWritable) {
File file = new File(getExternalFilesDir(null), “myfile.txt”);
FileOutputStream fos = new FileOutputStream(file);
fos.write(“Hello, External World!”.getBytes());
fos.close();
}

// Reading the file from external storage
FileInputStream fis = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
String fileContent = sb.toString();

Scoped Storage (Android 10+):

With Android 10, Google introduced Scoped Storage, which limits the app’s access to external storage. Apps are confined to their private directories on external storage but can request access to shared storage locations for specific use cases.

// Saving an image to the shared Pictures directory
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, “myimage.jpg”);
values.put(MediaStore.Images.Media.MIME_TYPE, “image/jpeg”);
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);

Uri uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream outputStream = getContentResolver().openOutputStream(uri);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.my_image);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();

Shared Preferences

What is it?

Shared Preferences is a key-value store that allows you to save small amounts of primitive data like booleans, floats, ints, longs, and strings. Data stored here is private to the app and is deleted when the app is uninstalled.

Use Cases:

  • Saving user settings and preferences.
  • Storing simple configuration values.

// Saving data in Shared Preferences
SharedPreferences sharedPref = getSharedPreferences(“MyPrefs”, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(“username”, “JohnDoe”);
editor.putBoolean(“isLoggedIn”, true);
editor.apply();

// Retrieving data from Shared Preferences
String username = sharedPref.getString(“username”, null);
boolean isLoggedIn = sharedPref.getBoolean(“isLoggedIn”, false);

SQLite Database

What is it?

SQLite is an embedded database provided by Android for storing structured data. It’s suitable for managing complex data relationships, performing queries, and transactions.

Use Cases:

  • Storing app data that requires complex queries or transactions.
  • Managing large datasets with structured relationships.

// Creating an SQLite database
public class MyDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = “MyDatabase.db”;
private static final int DATABASE_VERSION = 1;

public MyDatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

@Override
public void onCreate(SQLiteDatabase db) {
    db.execSQL("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER)");
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    db.execSQL("DROP TABLE IF EXISTS users");
    onCreate(db);
}

}

// Inserting data into SQLite
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(“name”, “John Doe”);
values.put(“age”, 30);
long newRowId = db.insert(“users”, null, values);

// Querying data from SQLite
Cursor cursor = db.query(“users”, null, null, null, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndexOrThrow(“name”));
int age = cursor.getInt(cursor.getColumnIndexOrThrow(“age”));
}
cursor.close();

Room Persistence Library

What is it?

Room is a part of Android’s Jetpack libraries and provides an abstraction layer over SQLite, making database access more robust and easier to work with.

Use Cases:

  • When you need an SQLite database but prefer a more modern, safer approach.
  • Managing database migrations and schema changes more easily.

// Define an entity
@Entity
public class User {
@PrimaryKey(autoGenerate = true)
public int uid;

@ColumnInfo(name = "name")
public String name;

@ColumnInfo(name = "age")
public int age;

}

// Create a DAO
@Dao
public interface UserDao {
@Insert
void insert(User user);

@Query("SELECT * FROM User")
List<User> getAllUsers();

}

// Create the database
@Database(entities = {User.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract UserDao userDao();
}

// Using the database
AppDatabase db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, “my-database”).build();
UserDao userDao = db.userDao();
userDao.insert(new User(“John Doe”, 30));
List users = userDao.getAllUsers();

Content Providers

What is it?

Content Providers allow you to manage and share app data across different applications. They are typically used to expose data to other apps or to consume data provided by other apps.

Use Cases:

  • Sharing data between different apps.
  • Accessing system data like contacts, media, etc.

// Querying contacts data using Content Provider
Cursor cursor = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
do {
String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
// Process contactName
} while (cursor.moveToNext());
cursor.close();
}

Conclusion

Each storage type in Android serves different purposes, and selecting the right one depends on your app’s requirements. Internal storage offers privacy and security, external storage provides user access to files, Shared Preferences is ideal for small key-value pairs, and SQLite/Room is perfect for structured data. Content Providers, on the other hand, are essential for sharing data between apps.

Understanding and using these storage options effectively can lead to more secure, efficient, and user-friendly Android applications.

Leave A Comment

Recommended Posts