0% found this document useful (0 votes)
2 views30 pages

Full Version Route Card

The document outlines a comprehensive implementation plan for an Android application designed to manage route cards. It includes a detailed project structure, key implementation files for user authentication, route card management, data export/import functionalities, PDF generation, QR code generation, and inventory monitoring. The application leverages Firebase for authentication and incorporates biometric security features, along with utilities for data handling and reporting.

Uploaded by

rowdygamer72002
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views30 pages

Full Version Route Card

The document outlines a comprehensive implementation plan for an Android application designed to manage route cards. It includes a detailed project structure, key implementation files for user authentication, route card management, data export/import functionalities, PDF generation, QR code generation, and inventory monitoring. The application leverages Firebase for authentication and incorporates biometric security features, along with utilities for data handling and reporting.

Uploaded by

rowdygamer72002
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

# Android Route Card Management System

I'll design a comprehensive Android application for managing route cards with all the
requested features. Here's a detailed implementation plan:

## 1. Project Structure

```
com.sivapress.routecard/
├── auth/

│ ├── LoginActivity.java

│ ├── RegisterActivity.java

│ ├── ForgotPasswordActivity.java

│ └── AuthViewModel.java

├── dashboard/

│ ├── MainActivity.java

│ ├── HomeFragment.java

│ ├── FavoritesFragment.java

│ ├── SearchFragment.java

│ └── SettingsFragment.java

├── routecard/

│ ├── CreateRouteCardActivity.java

│ ├── ViewRouteCardActivity.java

│ ├── EditRouteCardActivity.java

│ ├── RouteCardListAdapter.java

│ └── RouteCardViewModel.java
├── reports/
│ ├── InventoryActivity.java

│ ├── ChartsActivity.java

│ └── ExportActivity.java

├── company/

│ ├── ProfileActivity.java

│ └── EventsActivity.java

├── utils/

│ ├── ExcelUtils.java

│ ├── PdfUtils.java

│ ├── QRCodeUtils.java

│ ├── SecurityUtils.java

│ └── BackupUtils.java

└── data/

├── models/

│ ├── RouteCard.java

│ ├── User.java

│ └── Event.java

├── local/

│ ├── AppDatabase.java

│ └── RouteCardDao.java

└── remote/

├── FirebaseService.java

└── ApiService.java

```
## 2. Key Implementation Files

### Firebase Authentication (auth package)

**LoginActivity.java**
```java
public class LoginActivity extends AppCompatActivity {
private EditText emailEditText, passwordEditText;
private Button loginButton;
private TextView forgotPasswordText, registerText;
private FirebaseAuth auth;

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

auth = FirebaseAuth.getInstance();

emailEditText = findViewById(R.id.emailEditText);
passwordEditText = findViewById(R.id.passwordEditText);
loginButton = findViewById(R.id.loginButton);
forgotPasswordText = findViewById(R.id.forgotPasswordText);
registerText = findViewById(R.id.registerText);
loginButton.setOnClickListener(v -> {
String email = emailEditText.getText().toString().trim();
String password = passwordEditText.getText().toString().trim();

if (validateInputs(email, password)) {
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
startActivity(new Intent(this, MainActivity.class));
finish();
} else {
Toast.makeText(this, "Authentication failed", Toast.LENGTH_SHORT).show();
}
});
}
});

forgotPasswordText.setOnClickListener(v -> {
startActivity(new Intent(this, ForgotPasswordActivity.class));
});

registerText.setOnClickListener(v -> {
startActivity(new Intent(this, RegisterActivity.class));
});
}

private boolean validateInputs(String email, String password) {


// Validation logic
return true;
}
}
```

**ForgotPasswordActivity.java**
```java
public class ForgotPasswordActivity extends AppCompatActivity {
private EditText emailEditText;
private Button resetButton;
private FirebaseAuth auth;

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

auth = FirebaseAuth.getInstance();
emailEditText = findViewById(R.id.emailEditText);
resetButton = findViewById(R.id.resetButton);
resetButton.setOnClickListener(v -> {
String email = emailEditText.getText().toString().trim();
if (!email.isEmpty()) {
auth.sendPasswordResetEmail(email)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
Toast.makeText(this, "Reset email sent", Toast.LENGTH_SHORT).show();
finish();
} else {
Toast.makeText(this, "Failed to send reset email",
Toast.LENGTH_SHORT).show();
}
});
}
});
}
}
```

### Route Card Management (routecard package)

**CreateRouteCardActivity.java**
```java
public class CreateRouteCardActivity extends AppCompatActivity {
private RouteCardViewModel viewModel;
private TextInputEditText routeCardNoEditText, partNameEditText, partNoEditText;
private Button saveButton;
private BiometricPrompt biometricPrompt;

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

viewModel = new ViewModelProvider(this).get(RouteCardViewModel.class);

// Initialize all form fields


routeCardNoEditText = findViewById(R.id.routeCardNoEditText);
partNameEditText = findViewById(R.id.partNameEditText);
partNoEditText = findViewById(R.id.partNoEditText);
// Initialize other fields...

saveButton = findViewById(R.id.saveButton);
saveButton.setOnClickListener(v -> authenticateAndSave());
}

private void authenticateAndSave() {


// Check if biometric authentication is available
if (SecurityUtils.isBiometricAvailable(this)) {
showBiometricPrompt();
} else {
// Fallback to PIN/pattern
showPinDialog();
}
}

private void showBiometricPrompt() {


biometricPrompt = new BiometricPrompt(this, ContextCompat.getMainExecutor(this),
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(@NonNull
BiometricPrompt.AuthenticationResult result) {
super.onAuthenticationSucceeded(result);
saveRouteCard();
}
});

BiometricPrompt.PromptInfo promptInfo = new BiometricPrompt.PromptInfo.Builder()


.setTitle("Authentication Required")
.setSubtitle("Authenticate to save route card")
.setNegativeButtonText("Cancel")
.build();

biometricPrompt.authenticate(promptInfo);
}

private void saveRouteCard() {


RouteCard routeCard = new RouteCard();
routeCard.setRouteCardNo(routeCardNoEditText.getText().toString());
routeCard.setPartName(partNameEditText.getText().toString());
routeCard.setPartNo(partNoEditText.getText().toString());
// Set other fields...

viewModel.insertRouteCard(routeCard).observe(this, success -> {


if (success) {
Toast.makeText(this, "Route card saved", Toast.LENGTH_SHORT).show();
generateQRCode(routeCard);
finish();
} else {
Toast.makeText(this, "Failed to save", Toast.LENGTH_SHORT).show();
}
});
}

private void generateQRCode(RouteCard routeCard) {


String qrData = "RouteCard:" + routeCard.getRouteCardNo();
Bitmap qrBitmap = QRCodeUtils.generateQRCode(qrData, 400, 400);
// Save QR code to storage and associate with route card
}
}
```
### Excel Export/Import (utils package)

**ExcelUtils.java**
```java
public class ExcelUtils {
public static void exportRouteCardToExcel(Context context, RouteCard routeCard) {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("Route Card");

// Create header row


Row headerRow = sheet.createRow(0);
headerRow.createCell(0).setCellValue("Route Card No");
headerRow.createCell(1).setCellValue("Part Name");
headerRow.createCell(2).setCellValue("Part No");
// Add more headers as needed

// Create data row


Row dataRow = sheet.createRow(1);
dataRow.createCell(0).setCellValue(routeCard.getRouteCardNo());
dataRow.createCell(1).setCellValue(routeCard.getPartName());
dataRow.createCell(2).setCellValue(routeCard.getPartNo());
// Add more data as needed

// Save the workbook


try {
String fileName = "RouteCard_" + routeCard.getRouteCardNo() + ".xls";
File file = new File(context.getExternalFilesDir(null), fileName);
FileOutputStream fos = new FileOutputStream(file);
workbook.write(fos);
fos.close();

// Share the file


Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/vnd.ms-excel");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
context.startActivity(Intent.createChooser(shareIntent, "Share Route Card"));
} catch (IOException e) {
e.printStackTrace();
}
}

public static RouteCard importRouteCardFromExcel(Context context, Uri fileUri) {


try {
InputStream inputStream = context.getContentResolver().openInputStream(fileUri);
Workbook workbook = new HSSFWorkbook(inputStream);
Sheet sheet = workbook.getSheetAt(0);

RouteCard routeCard = new RouteCard();

// Assuming first row is header, second row is data


Row dataRow = sheet.getRow(1);
routeCard.setRouteCardNo(dataRow.getCell(0).getStringCellValue());
routeCard.setPartName(dataRow.getCell(1).getStringCellValue());
routeCard.setPartNo(dataRow.getCell(2).getStringCellValue());
// Import other fields...

return routeCard;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
```

### PDF Generation (utils package)

**PdfUtils.java**
```java
public class PdfUtils {
public static void generateRouteCardPdf(Context context, RouteCard routeCard) {
// Create a new PDF document
PdfDocument document = new PdfDocument();

// Create a page description


PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595, 842,
1).create();

// Start a new page


PdfDocument.Page page = document.startPage(pageInfo);

// Get the page's canvas


Canvas canvas = page.getCanvas();

// Create paint objects


Paint titlePaint = new Paint();
titlePaint.setColor(Color.BLACK);
titlePaint.setTextSize(18);
titlePaint.setTextAlign(Paint.Align.CENTER);

Paint textPaint = new Paint();


textPaint.setColor(Color.BLACK);
textPaint.setTextSize(12);

// Draw the title


canvas.drawText("SIVA PRESS COMPONENTS - JOB ROUTE CARD", 297, 50, titlePaint);

// Draw route card details


canvas.drawText("Route Card No: " + routeCard.getRouteCardNo(), 50, 100, textPaint);
canvas.drawText("Part Name: " + routeCard.getPartName(), 50, 120, textPaint);
canvas.drawText("Part No: " + routeCard.getPartNo(), 50, 140, textPaint);
// Add more details...

// Generate QR code and draw it


Bitmap qrBitmap = QRCodeUtils.generateQRCode(routeCard.getRouteCardNo(), 200,
200);
canvas.drawBitmap(qrBitmap, 400, 100, null);

// Finish the page


document.finishPage(page);

// Save the document


String fileName = "RouteCard_" + routeCard.getRouteCardNo() + ".pdf";
File file = new File(context.getExternalFilesDir(null), fileName);

try {
document.writeTo(new FileOutputStream(file));

// Share the PDF


Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
context.startActivity(Intent.createChooser(shareIntent, "Share Route Card PDF"));
} catch (IOException e) {
e.printStackTrace();
}
// Close the document
document.close();
}
}
```

### QR Code Generation (utils package)

**QRCodeUtils.java**
```java
public class QRCodeUtils {
public static Bitmap generateQRCode(String content, int width, int height) {
Map<EncodeHintType, Object> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

try {
BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE,
width, height, hints);
int[] pixels = new int[width * height];

for (int y = 0; y < height; y++) {


for (int x = 0; x < width; x++) {
pixels[y * width + x] = bitMatrix.get(x, y) ? Color.BLACK : Color.WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
} catch (WriterException e) {
e.printStackTrace();
return null;
}
}

public static void saveQRCodeToStorage(Context context, Bitmap qrBitmap, String


routeCardNo) {
try {
String fileName = "QR_" + routeCardNo + ".png";
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES),
fileName);

FileOutputStream fos = new FileOutputStream(file);


qrBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();

// Update the route card with QR code path


RouteCardViewModel viewModel = new ViewModelProvider((Activity)
context).get(RouteCardViewModel.class);
viewModel.updateRouteCardQRPath(routeCardNo, file.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
}
}
```

### Security (utils package)

**SecurityUtils.java**
```java
public class SecurityUtils {
public static boolean isBiometricAvailable(Context context) {
BiometricManager biometricManager = BiometricManager.from(context);
return biometricManager.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
}

public static void setupPinAuth(Activity activity, AuthCallback callback) {


PinLockView pinLockView = new PinLockView(activity);
PinLockListener pinLockListener = new PinLockListener() {
@Override
public void onComplete(String pin) {
// Verify pin from SharedPreferences
String savedPin = getSavedPin(activity);
if (pin.equals(savedPin)) {
callback.onSuccess();
} else {
callback.onFailure();
}
}

@Override
public void onEmpty() {}

@Override
public void onPinChange(int pinLength, String intermediatePin) {}
};

pinLockView.setPinLockListener(pinLockListener);

AlertDialog dialog = new AlertDialog.Builder(activity)


.setTitle("Enter PIN")
.setView(pinLockView)
.setNegativeButton("Cancel", null)
.create();

dialog.show();
}

private static String getSavedPin(Context context) {


SharedPreferences prefs = context.getSharedPreferences("auth_prefs",
Context.MODE_PRIVATE);
return prefs.getString("user_pin", "");
}
public interface AuthCallback {
void onSuccess();
void onFailure();
}
}
```

### Inventory Monitoring (reports package)

**InventoryActivity.java**
```java
public class InventoryActivity extends AppCompatActivity {
private PieChart pieChart;
private TextView totalTextView, balanceTextView, deliveredTextView;
private RouteCardViewModel viewModel;

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

pieChart = findViewById(R.id.pieChart);
totalTextView = findViewById(R.id.totalTextView);
balanceTextView = findViewById(R.id.balanceTextView);
deliveredTextView = findViewById(R.id.deliveredTextView);

viewModel = new ViewModelProvider(this).get(RouteCardViewModel.class);

setupPieChart();
observeInventoryData();
}

private void setupPieChart() {


pieChart.setUsePercentValues(true);
pieChart.getDescription().setEnabled(false);
pieChart.setExtraOffsets(5, 10, 5, 5);
pieChart.setDragDecelerationFrictionCoef(0.95f);
pieChart.setDrawHoleEnabled(true);
pieChart.setHoleColor(Color.WHITE);
pieChart.setTransparentCircleRadius(61f);

Legend l = pieChart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
l.setOrientation(Legend.LegendOrientation.VERTICAL);
l.setDrawInside(false);
l.setXEntrySpace(7f);
l.setYEntrySpace(0f);
l.setYOffset(0f);
}

private void observeInventoryData() {


viewModel.getInventorySummary().observe(this, summary -> {
if (summary != null) {
totalTextView.setText(String.valueOf(summary.getTotal()));
balanceTextView.setText(String.valueOf(summary.getBalance()));
deliveredTextView.setText(String.valueOf(summary.getDelivered()));

ArrayList<PieEntry> entries = new ArrayList<>();


entries.add(new PieEntry(summary.getBalance(), "Balance"));
entries.add(new PieEntry(summary.getDelivered(), "Delivered"));

PieDataSet dataSet = new PieDataSet(entries, "Route Card Status");


dataSet.setColors(ColorTemplate.MATERIAL_COLORS);
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);

PieData data = new PieData(dataSet);


data.setValueTextSize(11f);
data.setValueTextColor(Color.WHITE);

pieChart.setData(data);
pieChart.highlightValues(null);
pieChart.invalidate();
}
});
}
}
```

## 3. Database Implementation

**AppDatabase.java**
```java
@Database(entities = {RouteCard.class, User.class, Event.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract RouteCardDao routeCardDao();
public abstract UserDao userDao();
public abstract EventDao eventDao();

private static volatile AppDatabase INSTANCE;

public static AppDatabase getDatabase(final Context context) {


if (INSTANCE == null) {
synchronized (AppDatabase.class) {
if (INSTANCE == null) {
INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
AppDatabase.class, "routecard_database")
.fallbackToDestructiveMigration()
.build();
}
}
}
return INSTANCE;
}
}
```

**RouteCardDao.java**
```java
@Dao
public interface RouteCardDao {
@Insert
long insert(RouteCard routeCard);

@Update
void update(RouteCard routeCard);

@Delete
void delete(RouteCard routeCard);

@Query("SELECT * FROM routecard ORDER BY createdDate DESC")


LiveData<List<RouteCard>> getAllRouteCards();
@Query("SELECT * FROM routecard WHERE isFavorite = 1 ORDER BY createdDate DESC")
LiveData<List<RouteCard>> getFavoriteRouteCards();

@Query("SELECT * FROM routecard WHERE routeCardNo LIKE :query OR partName LIKE


:query OR partNo LIKE :query")
LiveData<List<RouteCard>> searchRouteCards(String query);

@Query("UPDATE routecard SET qrCodePath = :path WHERE routeCardNo =


:routeCardNo")
void updateQrCodePath(String routeCardNo, String path);

@Query("SELECT COUNT(*) FROM routecard")


LiveData<Integer> getTotalCount();

@Query("SELECT COUNT(*) FROM routecard WHERE status = 'DELIVERED'")


LiveData<Integer> getDeliveredCount();
}
```

## 4. Firebase Integration

**FirebaseService.java**
```java
public class FirebaseService {
private FirebaseFirestore db;
private FirebaseStorage storage;
private FirebaseAuth auth;

public FirebaseService() {
db = FirebaseFirestore.getInstance();
storage = FirebaseStorage.getInstance();
auth = FirebaseAuth.getInstance();
}

public Task<Void> saveRouteCard(RouteCard routeCard) {


return db.collection("routeCards")
.document(routeCard.getRouteCardNo())
.set(routeCard);
}

public Task<DocumentSnapshot> getRouteCard(String routeCardNo) {


return db.collection("routeCards")
.document(routeCardNo)
.get();
}

public Task<UploadTask.TaskSnapshot> uploadQrCode(String routeCardNo, Bitmap


qrBitmap) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
qrBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] data = baos.toByteArray();
StorageReference ref = storage.getReference()
.child("qr_codes")
.child(routeCardNo + ".png");

return ref.putBytes(data);
}

public Task<Uri> getQrCodeDownloadUrl(String routeCardNo) {


return storage.getReference()
.child("qr_codes")
.child(routeCardNo + ".png")
.getDownloadUrl();
}

public Task<Void> backupData(List<RouteCard> routeCards) {


Map<String, Object> backupData = new HashMap<>();
backupData.put("timestamp", FieldValue.serverTimestamp());
backupData.put("routeCards", routeCards);

return db.collection("backups")
.document(auth.getCurrentUser().getUid() + "_" + System.currentTimeMillis())
.set(backupData);
}
}
```
## 5. UI Design Considerations

1. **Premium UI Design**:
- Use Material Design 3 components
- Implement dark/light theme switching
- Custom animations and transitions
- Card-based layout for route cards

2. **Theme Switching**:
```java
public class SettingsFragment extends Fragment {
private SwitchMaterial darkModeSwitch;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_settings, container, false);

darkModeSwitch = view.findViewById(R.id.darkModeSwitch);

// Get current theme


int currentNightMode = getResources().getConfiguration().uiMode &
Configuration.UI_MODE_NIGHT_MASK;
darkModeSwitch.setChecked(currentNightMode == Configuration.UI_MODE_NIGHT_YES);
darkModeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
AppCompatDelegate.setDefaultNightMode(
isChecked ? AppCompatDelegate.MODE_NIGHT_YES :
AppCompatDelegate.MODE_NIGHT_NO);
requireActivity().recreate();
});

return view;
}
}
```

## 6. Additional Features

1. **Company Profile and Events**:


- Display company information with images
- Gallery for events with photo/video upload capability
- Firebase Storage integration for media files

2. **Data Backup**:
- Local backup to device storage
- Cloud backup to Firebase
- Scheduled automatic backups

3. **Search and Favorites**:


- Full-text search across all route card fields
- Favorite marking for quick access
- Filtering by status, date range, etc.

## 7. Dependencies (build.gradle)

```gradle
dependencies {
// Firebase
implementation platform('com.google.firebase:firebase-bom:32.0.0')
implementation 'com.google.firebase:firebase-auth'
implementation 'com.google.firebase:firebase-firestore'
implementation 'com.google.firebase:firebase-storage'

// Room Database
implementation "androidx.room:room-runtime:2.4.0"
kapt "androidx.room:room-compiler:2.4.0"
implementation "androidx.room:room-ktx:2.4.0"

// Apache POI for Excel


implementation 'org.apache.poi:poi:5.2.0'
implementation 'org.apache.poi:poi-ooxml:5.2.0'

// QR Code
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
// Biometric
implementation "androidx.biometric:biometric:1.1.0"

// Charts
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

// PDF Generation
implementation 'com.itextpdf:itext7-core:7.1.15'

// Material Design
implementation 'com.google.android.material:material:1.6.0'

// ViewModel and LiveData


implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0"

// Image Loading
implementation 'com.github.bumptech.glide:glide:4.12.0'
kapt 'com.github.bumptech.glide:compiler:4.12.0'
}
```

This comprehensive implementation covers all the requested features including authentication,
route card management with QR codes, Excel/PDF export/import, inventory monitoring with
charts, security features, and premium UI design. The architecture follows modern Android
development best practices with ViewModel, LiveData, and Room for local persistence,
complemented by Firebase for cloud services.

You might also like