diff --git a/app/src/main/java/com/fieldbook/tracker/preferences/GeneralKeys.java b/app/src/main/java/com/fieldbook/tracker/preferences/GeneralKeys.java index d2cda4354..ae18a03b0 100644 --- a/app/src/main/java/com/fieldbook/tracker/preferences/GeneralKeys.java +++ b/app/src/main/java/com/fieldbook/tracker/preferences/GeneralKeys.java @@ -187,6 +187,9 @@ public class GeneralKeys { //Calendar Trait public static final String CALENDAR_LAST_SAVED_DATE = "com.fieldbook.tracker.CALENDAR_LAST_SAVED_DATE"; + //Zebra Label Print Trait + public static final String LABEL_PRINT_DEVICE_NAME = "LABEL_PRINT_DEVICE_NAME"; + //Dialog Export public static final String DIALOG_EXPORT_BUNDLE_CHECKED = "com.fieldbook.tracker.DIALOG_EXPORT_BUNDLE_CHECKED"; diff --git a/app/src/main/java/com/fieldbook/tracker/traits/LabelPrintTraitLayout.java b/app/src/main/java/com/fieldbook/tracker/traits/LabelPrintTraitLayout.java index d588f5819..bf28f0d1b 100644 --- a/app/src/main/java/com/fieldbook/tracker/traits/LabelPrintTraitLayout.java +++ b/app/src/main/java/com/fieldbook/tracker/traits/LabelPrintTraitLayout.java @@ -25,6 +25,7 @@ import com.fieldbook.tracker.R; import com.fieldbook.tracker.activities.CollectActivity; import com.fieldbook.tracker.preferences.GeneralKeys; +import com.fieldbook.tracker.utilities.BluetoothChooseCallback; import com.fieldbook.tracker.utilities.BluetoothUtil; import com.fieldbook.tracker.utilities.Constants; @@ -54,6 +55,7 @@ public class LabelPrintTraitLayout extends BaseTraitLayout { private Spinner barcodefield; private Spinner labelcopies; + private ImageButton connectPrinter; private ImageView label; private ImageButton printLabel; @@ -158,8 +160,9 @@ public void init(Activity act) { mActivity = act; + connectPrinter = act.findViewById(R.id.connectPrinterButton); printLabel = act.findViewById(R.id.printLabelButton); - + LocalBroadcastManager.getInstance(getContext()).unregisterReceiver(mPrinterMessageReceiver); LocalBroadcastManager.getInstance(getContext()).registerReceiver(mPrinterMessageReceiver, new IntentFilter("printer_message")); @@ -292,6 +295,17 @@ public void onNothingSelected(AdapterView arg0) { e.printStackTrace(); } + connectPrinter.setOnClickListener(view -> { + + mBluetoothUtil.choose(getContext(), new BluetoothChooseCallback() { + @Override + public void onDeviceChosen(String newDeviceName) { + Log.d("LabelPrintTraitLayout", "Chosen printerName is " + newDeviceName); + saveDeviceNamePreference(newDeviceName); + } + }); + + }); /* * This section handles print events. TODO: Create a label prototype based class. Move most of this logic to a function/class. chaneylc 8/26/2020 @@ -389,7 +403,11 @@ public void onNothingSelected(AdapterView arg0) { labelData = labelData.replace("size2", size2); labelData = labelData.replace("size3", size3); labelData = labelData.replace("size4", size4); - labelData = labelData.replace("barcode", barcode); + if (barcode.isEmpty()) { // remove barcode if it will not encode anything + labelData = labelData.replace("^BQ,,sizeb^FDMA,barcode^FS", ""); + } else { + labelData = labelData.replace("barcode", barcode); + } labelData = labelData.replace("sizeb", Integer.toString(barcode_size)); } @@ -413,7 +431,20 @@ public void onNothingSelected(AdapterView arg0) { * This bluetooth utility class is used to connect with a paired printer and send print commands. * A local broadcast receiver is used to communicate with the print thread within this utility class. */ - mBluetoothUtil.print(getContext(), size, labels); + String printerName = getPrefs().getString(GeneralKeys.LABEL_PRINT_DEVICE_NAME, null); + Log.d("LabelPrintTraitLayout", "retrieved printerName is " + printerName); + if (printerName == null) { + mBluetoothUtil.choose(getContext(), new BluetoothChooseCallback() { + @Override + public void onDeviceChosen(String newDeviceName) { + Log.d("LabelPrintTraitLayout", "Chosen printerName is " + newDeviceName); + saveDeviceNamePreference(newDeviceName); + mBluetoothUtil.print(getContext(), newDeviceName, size, labels); + } + }); + } else { + mBluetoothUtil.print(getContext(), printerName, size, labels); + } } } } else { @@ -424,6 +455,12 @@ public void onNothingSelected(AdapterView arg0) { }); } + private void saveDeviceNamePreference(String newDeviceName) { + SharedPreferences.Editor editor = getPrefs().edit(); + editor.putString(GeneralKeys.LABEL_PRINT_DEVICE_NAME, newDeviceName); + editor.apply(); + } + @Override public void deleteTraitListener() { diff --git a/app/src/main/java/com/fieldbook/tracker/utilities/BluetoothUtil.kt b/app/src/main/java/com/fieldbook/tracker/utilities/BluetoothUtil.kt index 4b4e82a09..a12806253 100644 --- a/app/src/main/java/com/fieldbook/tracker/utilities/BluetoothUtil.kt +++ b/app/src/main/java/com/fieldbook/tracker/utilities/BluetoothUtil.kt @@ -3,82 +3,79 @@ package com.fieldbook.tracker.utilities import android.bluetooth.BluetoothAdapter import android.bluetooth.BluetoothDevice import android.content.Context +import android.content.SharedPreferences +import android.util.Log import android.widget.RadioButton import android.widget.RadioGroup import androidx.appcompat.app.AlertDialog import com.fieldbook.tracker.R +import com.fieldbook.tracker.preferences.GeneralKeys - +interface BluetoothChooseCallback { + fun onDeviceChosen(deviceName: String) +} //Bluetooth Utility class for printing ZPL code and choosing bluetooth devices to print from. class BluetoothUtil { - private var mBtName: String = String() - private val mBluetoothAdapter: BluetoothAdapter? by lazy { BluetoothAdapter.getDefaultAdapter() } //operation that uses the provided context to prompt the user for a paired bluetooth device - private fun choose(ctx: Context, f: () -> Unit) { + fun choose(ctx: Context, callback: BluetoothChooseCallback) { - if (mBtName.isBlank()) { + var deviceName: String = "" - mBluetoothAdapter?.let { + mBluetoothAdapter?.let { - val pairedDevices = it.bondedDevices + val pairedDevices = it.bondedDevices - val map = HashMap() + val map = HashMap() - val input = RadioGroup(ctx) + val input = RadioGroup(ctx) - pairedDevices.forEachIndexed { _, t -> - val button = RadioButton(ctx) - button.text = t.name - input.addView(button) - map[button.id] = t - } + pairedDevices.forEachIndexed { _, t -> + val button = RadioButton(ctx) + button.text = t.name + input.addView(button) + map[button.id] = t + } - val builder = AlertDialog.Builder(ctx).apply { + val builder = AlertDialog.Builder(ctx).apply { - setTitle(context.getString(R.string.bluetooth_printer_choose_device_title)) + setTitle(context.getString(R.string.bluetooth_printer_choose_device_title)) - setView(input) + setView(input) - setNegativeButton(android.R.string.cancel) { _, _ -> + setNegativeButton(android.R.string.cancel) { _, _ -> - } + } - setPositiveButton(android.R.string.ok) { _, _ -> + setPositiveButton(android.R.string.ok) { _, _ -> - if (input.checkedRadioButtonId == -1) return@setPositiveButton - else { - mBtName = map[input.checkedRadioButtonId]?.name ?: "" - } - f() + if (input.checkedRadioButtonId == -1) return@setPositiveButton + else { + Log.d("BluetoothUtil", "Setting mBtName") + deviceName = map[input.checkedRadioButtonId]?.name ?: "" + Log.d("BluetoothUtil", "Selected Bluetooth Device: $deviceName") + callback.onDeviceChosen(deviceName) } } - - builder.show() } - } else f() + builder.show() + } } /** - * This function will first ask the user to select a printer. - * As long as the same object is used the user only needs to ask once. - * This sends a list of label commands, and only updates the printer message when the + * This function will send a list of label commands to the printer, and only updates the printer message when the * button is pressed. */ - fun print(ctx: Context, size: String, labelCommand: List) { - - choose(ctx) { - - if (labelCommand.isNotEmpty()) { - - PrintThread(ctx, mBtName).print(size, labelCommand) - - } + fun print(ctx: Context, printerName: String, size: String, labelCommand: List) { + Log.d("BluetoothUtil", "Label Command is: $labelCommand") + if (labelCommand.isNotEmpty()) { + Log.d("BluetoothUtil", "printing to $printerName") + PrintThread(ctx, printerName).print(size, labelCommand) } } -} \ No newline at end of file +} diff --git a/app/src/main/res/drawable/connection.xml b/app/src/main/res/drawable/connection.xml new file mode 100644 index 000000000..84a7a9e78 --- /dev/null +++ b/app/src/main/res/drawable/connection.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/src/main/res/layout/trait_labelprint.xml b/app/src/main/res/layout/trait_labelprint.xml index ac4e5a8dc..8f2289018 100644 --- a/app/src/main/res/layout/trait_labelprint.xml +++ b/app/src/main/res/layout/trait_labelprint.xml @@ -14,10 +14,23 @@ android:gravity="center" android:orientation="horizontal"> + + + android:layout_width="0dp" + android:layout_weight="3" + android:maxLines="1" /> + android:layout_width="0dp" + android:layout_weight="3" + android:maxLines="1" /> + android:layout_width="0dp" + android:layout_weight="3" + android:maxLines="1" /> + android:layout_width="0dp" + android:layout_weight="3" + android:maxLines="1" /> + android:layout_width="0dp" + android:layout_weight="3" + android:maxLines="1" /> Printer not connected No device paired + Button which connects a printer. Label preview. Button which prints labels configured in this dialog.