Initialize Schnappix Photo Booth application with custom UVC camera, silent Wi-Fi IPP printing, local gallery storage, and kiosk screen pinning support
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
const { withAndroidManifest, withDangerousMod } = require('@expo/config-plugins');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const withKioskAdmin = (config) => {
|
||||
// 1. Modify AndroidManifest.xml
|
||||
config = withAndroidManifest(config, async (config) => {
|
||||
const androidManifest = config.modResults;
|
||||
const mainApplication = androidManifest.manifest.application[0];
|
||||
|
||||
if (!mainApplication.receiver) {
|
||||
mainApplication.receiver = [];
|
||||
}
|
||||
|
||||
// Check if receiver is already added to avoid duplication
|
||||
const receiverExists = mainApplication.receiver.some(
|
||||
(r) => r.$['android:name'] === 'expo.modules.kioskmode.AdminReceiver'
|
||||
);
|
||||
|
||||
if (!receiverExists) {
|
||||
mainApplication.receiver.push({
|
||||
$: {
|
||||
'android:name': 'expo.modules.kioskmode.AdminReceiver',
|
||||
'android:label': 'Schnappix Kiosk Admin',
|
||||
'android:permission': 'android.permission.BIND_DEVICE_ADMIN',
|
||||
'android:exported': 'true',
|
||||
},
|
||||
'meta-data': [
|
||||
{
|
||||
$: {
|
||||
'android:name': 'android.app.device_admin',
|
||||
'android:resource': '@xml/device_admin_receiver',
|
||||
},
|
||||
},
|
||||
],
|
||||
'intent-filter': [
|
||||
{
|
||||
action: [
|
||||
{ $: { 'android:name': 'android.app.action.DEVICE_ADMIN_ENABLED' } },
|
||||
{ $: { 'android:name': 'android.app.action.DEVICE_ADMIN_DISABLED' } },
|
||||
],
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
|
||||
// 2. Create the device_admin_receiver.xml resource file in android/app/src/main/res/xml/
|
||||
config = withDangerousMod(config, [
|
||||
'android',
|
||||
async (config) => {
|
||||
const { projectRoot } = config.modRequest;
|
||||
const resXmlDir = path.join(projectRoot, 'android/app/src/main/res/xml');
|
||||
|
||||
// Ensure res/xml directory exists
|
||||
if (!fs.existsSync(resXmlDir)) {
|
||||
fs.mkdirSync(resXmlDir, { recursive: true });
|
||||
}
|
||||
|
||||
const xmlFilePath = path.join(resXmlDir, 'device_admin_receiver.xml');
|
||||
const xmlContent = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-policies>
|
||||
<force-lock />
|
||||
</uses-policies>
|
||||
</device-admin>`;
|
||||
|
||||
fs.writeFileSync(xmlFilePath, xmlContent, 'utf8');
|
||||
return config;
|
||||
},
|
||||
]);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
module.exports = withKioskAdmin;
|
||||
@@ -0,0 +1,29 @@
|
||||
const { withAndroidManifest } = require('@expo/config-plugins');
|
||||
|
||||
const withUsbCamera = (config) => {
|
||||
return withAndroidManifest(config, async (config) => {
|
||||
const androidManifest = config.modResults;
|
||||
|
||||
if (!androidManifest.manifest['uses-feature']) {
|
||||
androidManifest.manifest['uses-feature'] = [];
|
||||
}
|
||||
|
||||
// Check if usb.host feature is already added
|
||||
const featureExists = androidManifest.manifest['uses-feature'].some(
|
||||
(f) => f.$['android:name'] === 'android.hardware.usb.host'
|
||||
);
|
||||
|
||||
if (!featureExists) {
|
||||
androidManifest.manifest['uses-feature'].push({
|
||||
$: {
|
||||
'android:name': 'android.hardware.usb.host',
|
||||
'android:required': 'false',
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return config;
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = withUsbCamera;
|
||||
Reference in New Issue
Block a user