From 283cba32396e510cb924065586199e69c94fd3c2 Mon Sep 17 00:00:00 2001 From: Trudu Laurent Date: Thu, 22 Aug 2024 15:33:22 +0200 Subject: [PATCH] Added StageNow PDF file to add an AudioVolUI profile called MAXIMUM (set all the volumes to maximum) Added old way of playing using MediaPlayer (for testing purposes) Added a button to activate AudioVolUI profile MAXIMUM --- StageNowAudioVolUIMgrProfileMAXIMUM.pdf | Bin 0 -> 5229 bytes hsdemo/build.gradle | 2 +- .../main/java/com/zebra/hsdemo/EMDKUtils.java | 484 ++++++++++++++++++ .../java/com/zebra/hsdemo/MainActivity.java | 115 ++++- hsdemo/src/main/res/layout/activity_main.xml | 52 +- settings.gradle | 3 + 6 files changed, 622 insertions(+), 34 deletions(-) create mode 100644 StageNowAudioVolUIMgrProfileMAXIMUM.pdf create mode 100644 hsdemo/src/main/java/com/zebra/hsdemo/EMDKUtils.java diff --git a/StageNowAudioVolUIMgrProfileMAXIMUM.pdf b/StageNowAudioVolUIMgrProfileMAXIMUM.pdf new file mode 100644 index 0000000000000000000000000000000000000000..884e085ba9d9f4c19e1dec5f96844d6fcc7ef85d GIT binary patch literal 5229 zcmbVQ2UJs8^H+KY5fD)zfb^0C5(u5pJAu%P637!mNiYNuPyta90i_q|D!qz;sEdfw z!A9?j(xf9rK!Ja<>+ZVWp7VX@{O`%hyYKhz%)FUi-L(NCY>_Ax<0 z5D>x5i%Crlj0_-o5{MFLYovjmxrLo1SceE;NdG{raU>r=0!_kr;P4(GZ4A+!fCc

7Db1K2H4)h%?og+ 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 literal 0 HcmV?d00001 diff --git a/hsdemo/build.gradle b/hsdemo/build.gradle index a5bf630..85cbfa5 100644 --- a/hsdemo/build.gradle +++ b/hsdemo/build.gradle @@ -38,5 +38,5 @@ dependencies { androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core implementation 'com.github.ltrudu:CriticalPermissionsHelper:+' - + compileOnly 'com.symbol:emdk:9.1.1' } \ No newline at end of file diff --git a/hsdemo/src/main/java/com/zebra/hsdemo/EMDKUtils.java b/hsdemo/src/main/java/com/zebra/hsdemo/EMDKUtils.java new file mode 100644 index 0000000..b51a48c --- /dev/null +++ b/hsdemo/src/main/java/com/zebra/hsdemo/EMDKUtils.java @@ -0,0 +1,484 @@ +package com.zebra.hsdemo; + +import android.content.Context; +import android.text.TextUtils; +import android.util.Log; +import android.util.Xml; + +import com.symbol.emdk.EMDKBase; +import com.symbol.emdk.EMDKException; +import com.symbol.emdk.EMDKManager; +import com.symbol.emdk.EMDKResults; +import com.symbol.emdk.ProfileManager; + +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.StringReader; +import java.util.ArrayList; + +public class EMDKUtils { + + public interface IResultCallbacks{ + void onSuccess(final String message, final String resultXML); + void onError(final String message, final String resultXML); + void onDebugStatus(final String message); + } + + protected enum EMessageType { + VERBOSE("VERBOSE"), + WARNING("WARNING"), + ERROR("ERROR"), + SUCCESS("SUCCESS"), + DEBUG("DEBUG"); + + String stringContent = ""; + EMessageType(String stringContent) { this.stringContent = stringContent;} + + public String toString() { + return stringContent; + } + + public static EMessageType fromString(String messageType) + { + switch(messageType) { + case "VERBOSE": + return VERBOSE; + case "WARNING": + return WARNING; + case "Error": + return ERROR; + case "SUCCESS": + return SUCCESS; + case "DEBUG": + return DEBUG; + default: + return null; + } + } + } + + // A class that will hold errors if it happens + protected class ErrorHolder + { + // Provides the error type for characteristic-error + protected String sErrorType = ""; + + // Provides the parm name for parm-error + protected String sParmName = ""; + + // Provides error description + protected String sErrorDescription = ""; + } + + private final static String TAG = "EMDKUtils"; + + // Profile content in XML + private String msProfileData = ""; + + // Profile name to execute + private String msProfileName = ""; + + //Declare a variable to store ProfileManager object + private ProfileManager mProfileManager = null; + + //Declare a variable to store EMDKManager object + private EMDKManager mEMDKManager = null; + + // An ArrayList that will contains errors if we find some + private ArrayList mErrors = new ArrayList<>(); + + // Error String + private String msErrorString = null; + + // Status returned by the profile in case of success + private String msStatusXMLResponse = ""; + + private Context mContext = null; + + private IResultCallbacks mIResultCallbacks = null; + + // EMDKListener implementation + private EMDKManager.EMDKListener mEMDKListener = new EMDKManager.EMDKListener() { + @Override + public void onOpened(EMDKManager emdkManager) { + logMessage("EMDKManager.EMDKListener.onOpened", EMessageType.DEBUG); + onEMDKManagerRetrieved(emdkManager); + } + + @Override + public void onClosed() { + logMessage("EMDKManager.EMDKListener.onClosed", EMessageType.DEBUG); + onEMDKManagerClosed(); + } + }; + + // Status Listener implementation (ensure that we retrieve the profile manager asynchronously + private EMDKManager.StatusListener mStatusListener = new EMDKManager.StatusListener() { + @Override + public void onStatus(EMDKManager.StatusData statusData, EMDKBase emdkBase) { + if(statusData.getResult() == EMDKResults.STATUS_CODE.SUCCESS) + { + ProfileManager profileManager = (ProfileManager)emdkBase; + if(profileManager != null) + onProfileManagerInitialized(profileManager); + else + { + logMessage("Casting error when retrieving ProfileManager.", EMessageType.ERROR); + profileManager = (ProfileManager) mEMDKManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE); + if(profileManager != null) { + logMessage("Profile manager retrieved synchronously with success", EMessageType.VERBOSE); + onProfileManagerInitialized(profileManager); + } + } + } + else + { + String errorMessage = "Error when trying to retrieve ProfileManager: " + getResultCode(statusData.getResult()); + logMessage(errorMessage, EMessageType.ERROR); + } + } + }; + + public EMDKUtils(Context context) + { + mContext = context; + } + + public void activateVolumeProfile(String audioProfileName, IResultCallbacks resultCallbacks) + { + mIResultCallbacks = resultCallbacks; + // Create profile content + msProfileName = "AudioVolumeMgr-1"; + msProfileData = "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + " \n" + + " \n" + + " \n" + + " \n" + + "\n" + + "\n"; + + // initialize profile manager processing + initializeEMDK(); + } + + private void initializeEMDK() + { + if(mEMDKManager == null) + { + EMDKResults results = null; + try + { + //The EMDKManager object will be created and returned in the callback. + results = EMDKManager.getEMDKManager(mContext.getApplicationContext(), mEMDKListener); + } + catch(Exception e) + { + logMessage("Error while requesting EMDKManager.\n" + e.getLocalizedMessage(), EMessageType.ERROR); + e.printStackTrace(); + return; + } + + //Check the return status of EMDKManager object creation. + if(results.statusCode == EMDKResults.STATUS_CODE.SUCCESS) { + logMessage("EMDKManager request command issued with success", EMessageType.DEBUG); + }else { + logMessage("EMDKManager request command error", EMessageType.ERROR); + } + } + else + { + onEMDKManagerRetrieved(mEMDKManager); + } + } + + private void onEMDKManagerRetrieved(EMDKManager emdkManager) + { + mEMDKManager = emdkManager; + logMessage("EMDK Manager retrieved.", EMessageType.DEBUG); + if(mProfileManager == null) + { + try { + logMessage("Requesting profile manager.", EMessageType.DEBUG); + logMessage("Current API version: " + android.os.Build.VERSION.SDK_INT, EMessageType.VERBOSE); + if(android.os.Build.VERSION.SDK_INT < 33) { + logMessage("Requesting profile manager Asynchonously", EMessageType.DEBUG); + emdkManager.getInstanceAsync(EMDKManager.FEATURE_TYPE.PROFILE, mStatusListener); + } + else + { + logMessage("Requesting profile manager synchronized", EMessageType.DEBUG); + ProfileManager profileManager = (ProfileManager) emdkManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE); + if(profileManager != null) + { + onProfileManagerInitialized(profileManager); + } + } + } catch (EMDKException e) { + logMessage("Error when trying to retrieve profile manager: " + e.getMessage(), EMessageType.ERROR); + } + } + else + { + logMessage("EMDK Manager already initialized.", EMessageType.DEBUG); + onProfileManagerInitialized(mProfileManager); + } + } + + private void onProfileManagerInitialized(ProfileManager profileManager) + { + mProfileManager = profileManager; + logMessage("Profile Manager retrieved.", EMessageType.DEBUG); + processMXContent(); + } + + private void processMXContent() + { + String[] params = new String[1]; + params[0] = msProfileData; + + if(mProfileManager == null) + { + logMessage("ProcessMXContent : Error : ProfileManager == null", EMessageType.ERROR); + if(mEMDKManager != null) { + logMessage("ProcessMXContent : Trying to retrieve profileManager synchronously", EMessageType.ERROR); + ProfileManager profileManager = (ProfileManager) mEMDKManager.getInstance(EMDKManager.FEATURE_TYPE.PROFILE); + if (profileManager != null) { + logMessage("ProcessMXContent, ProfileManager retrieved syncrhonously.", EMessageType.VERBOSE); + mProfileManager = profileManager; + } + else + { + logMessage("ProcessMXContent : Error : Could not retrieve ProfileManager syncrhonously.", EMessageType.VERBOSE); + onProfileExecutedError("ProcessMXContent : Error : Could not retrieve ProfileManager syncrhonously."); + return; + } + } + else { + logMessage("ProcessMXContent : Error : mEMDKManager == null", EMessageType.ERROR); + onProfileExecutedError("ProcessMXContent : Error : mEMDKManager == null"); + return; + } + } + + EMDKResults results = mProfileManager.processProfile(msProfileName, ProfileManager.PROFILE_FLAG.SET, params); + + //Check the return status of processProfile + if(results.statusCode == EMDKResults.STATUS_CODE.CHECK_XML) { + + // Get XML response as a String + msStatusXMLResponse = results.getStatusString(); + + try { + // Empty Error Holder Array List if it already exists + mErrors.clear(); + + // Create instance of XML Pull Parser to parse the response + XmlPullParser parser = Xml.newPullParser(); + // Provide the string response to the String Reader that reads + // for the parser + parser.setInput(new StringReader(msStatusXMLResponse)); + // Call method to parse the response + parseXML(parser); + + if ( mErrors.size() == 0 ) { + + logMessage("Profile executed with success: " + msProfileName, EMessageType.SUCCESS); + onProfileExecutedWithSuccess(); + } + else { + String errorMessage = ""; + for(ErrorHolder error : mErrors) + { + errorMessage += "Profile processing error.\t" + "Type:" + error.sErrorType + "\tParamName:" + error.sParmName + "\tDescription:" + error.sErrorDescription; + } + logMessage(errorMessage, EMessageType.ERROR); + onProfileExecutedError(errorMessage); + return; + } + + } catch (XmlPullParserException e) { + String errorMessage = "Error while trying to parse ProfileManager XML Response: " + e.getLocalizedMessage(); + logMessage(errorMessage, EMessageType.ERROR); + onProfileExecutedError(errorMessage); + return; + } + } + else if(results.statusCode == EMDKResults.STATUS_CODE.SUCCESS) + { + logMessage("Profile executed with success: " + msProfileName, EMessageType.DEBUG); + onProfileExecutedWithSuccess(); + return; + } + else + { + String errorMessage = "Profile update failed." + getResultCode(results.statusCode) + "\nProfil:\n" + msProfileName; + logMessage(errorMessage, EMessageType.ERROR); + onProfileExecutedError(errorMessage); + return; + } + } + + private void onProfileExecutedWithSuccess() + { + cleanUp(); + if(mIResultCallbacks != null) + { + mIResultCallbacks.onSuccess("Success applying profile:" + msProfileName + "\nProfileData:" + msProfileData, msStatusXMLResponse); + } + + } + + private void onProfileExecutedError(String message) + { + cleanUp(); + if(mIResultCallbacks != null) + { + mIResultCallbacks.onError("Error on profile: " + msProfileName + "\nError:" + message + "\nProfileData:" + msProfileData, msStatusXMLResponse); + } + + } + + private void onProfileExecutedStatusChanged(String message) + { + if(mIResultCallbacks != null) + { + mIResultCallbacks.onDebugStatus(message); + } + } + + // Method to parse the XML response using XML Pull Parser + private void parseXML(XmlPullParser myParser) { + int event; + try { + // Retrieve error details if parm-error/characteristic-error in the response XML + event = myParser.getEventType(); + // An object that will store a temporary error holder if an error characteristic is found + ErrorHolder tempErrorHolder = null; + //logMessage("XML document", EMessageType.VERBOSE); + while (event != XmlPullParser.END_DOCUMENT) { + String name = myParser.getName(); + switch (event) { + case XmlPullParser.START_TAG: + //logMessage("XML Element:<" + myParser.getText()+">", EMessageType.VERBOSE); + if (name.equals("characteristic-error")) + { + if(tempErrorHolder == null) + tempErrorHolder = new ErrorHolder(); + tempErrorHolder.sErrorType = myParser.getAttributeValue(null, "type"); + if(tempErrorHolder.sParmName != null && TextUtils.isEmpty(tempErrorHolder.sParmName) == false) + { + msErrorString += "Nom: " + tempErrorHolder.sParmName + "\nType: " + tempErrorHolder.sErrorType + "\nDescription: " + tempErrorHolder.sErrorDescription + ")"; + mErrors.add(tempErrorHolder); + tempErrorHolder = null; + } + } + else if (name.equals("parm-error")) + { + if(tempErrorHolder == null) + tempErrorHolder = new ErrorHolder(); + tempErrorHolder.sParmName = myParser.getAttributeValue(null, "name"); + tempErrorHolder.sErrorDescription = myParser.getAttributeValue(null, "desc"); + if(tempErrorHolder.sErrorType != null && TextUtils.isEmpty(tempErrorHolder.sErrorType) == false) + { + msErrorString += "Nom: " + tempErrorHolder.sParmName + "\nType: " + tempErrorHolder.sErrorType + "\nDescription: " + tempErrorHolder.sErrorDescription + ")"; + mErrors.add(tempErrorHolder); + tempErrorHolder = null; + } + } + break; + case XmlPullParser.END_TAG: + //logMessage("XML Element:", EMessageType.VERBOSE); + break; + } + event = myParser.next(); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void onEMDKManagerClosed() + { + cleanUp(); + } + + private void cleanUp() + { + if(mProfileManager != null) + { + mProfileManager = null; + logMessage("Profile Manager reseted.", EMessageType.DEBUG); + } + + //This callback will be issued when the EMDK closes unexpectedly. + if (mEMDKManager != null) { + mEMDKManager.release(); + logMessage("EMDKManager released.", EMessageType.DEBUG); + mEMDKManager = null; + logMessage("EMDKManager reseted.", EMessageType.DEBUG); + } + } + + + private void logMessage(String message, EMessageType messageType) + { + switch(messageType) + { + case ERROR: + Log.e(TAG, message); + onProfileExecutedStatusChanged("ERROR:" + message); + break; + case SUCCESS: + Log.v(TAG, message); + onProfileExecutedStatusChanged("SUCCESS:" + message); + break; + case VERBOSE: + Log.v(TAG, message); + onProfileExecutedStatusChanged("VERBOSE:" + message); + break; + case WARNING: + Log.w(TAG, message); + onProfileExecutedStatusChanged("WARNING:" + message); + break; + case DEBUG: + Log.d(TAG,message); + onProfileExecutedStatusChanged("DEBUG:" + message); + } + } + + private String getResultCode(EMDKResults.STATUS_CODE aStatusCode) + { + switch (aStatusCode) + { + case FAILURE: + return "FAILURE"; + case NULL_POINTER: + return "NULL_POINTER"; + case EMPTY_PROFILENAME: + return "EMPTY_PROFILENAME"; + case EMDK_NOT_OPENED: + return "EMDK_NOT_OPENED"; + case CHECK_XML: + return "CHECK_XML"; + case PREVIOUS_REQUEST_IN_PROGRESS: + return "PREVIOUS_REQUEST_IN_PROGRESS"; + case PROCESSING: + return "PROCESSING"; + case NO_DATA_LISTENER: + return "NO_DATA_LISTENER"; + case FEATURE_NOT_READY_TO_USE: + return "FEATURE_NOT_READY_TO_USE"; + case FEATURE_NOT_SUPPORTED: + return "FEATURE_NOT_SUPPORTED"; + case UNKNOWN: + default: + return "UNKNOWN"; + } + } +} diff --git a/hsdemo/src/main/java/com/zebra/hsdemo/MainActivity.java b/hsdemo/src/main/java/com/zebra/hsdemo/MainActivity.java index dfd99d4..18d11b3 100644 --- a/hsdemo/src/main/java/com/zebra/hsdemo/MainActivity.java +++ b/hsdemo/src/main/java/com/zebra/hsdemo/MainActivity.java @@ -89,6 +89,7 @@ public class MainActivity extends AppCompatActivity { private List devices; private boolean targetBt = false; + private EMDKUtils emdkUtils = null; AudioRecord recorder = null; Thread recordingThread = null; @@ -191,10 +192,24 @@ public void onClick(View view) { stopRecording(); } }); + + findViewById(R.id.btPlayWithMPOld).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + playWithMediaPlayerOld(); + } + }); + findViewById(R.id.btPlayWithMP).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - playWithMediaPlayer(); + new Thread(new Runnable() { + @Override + public void run() { + // Your code here + playWithMediaPlayer(); + } + }).start(); } }); @@ -212,15 +227,13 @@ public void run() { } }); - - /*findViewById(R.id.btPlayWithATMG).setOnClickListener(new View.OnClickListener() - { + findViewById(R.id.btActivateVolumeProfile).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - playPcmFileWithAudioTrack(true); + activateMaximumAudioProfile(); } }); - */ + setButtonVisibility(true); TextView tvRecordingGain = findViewById(R.id.tvRecordingGain); @@ -341,7 +354,7 @@ private void startRecording(){ audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); - bufSize = AudioRecord.getMinBufferSize(sampleRate, channelInConfig, audioFormat)*10; + bufSize = AudioRecord.getMinBufferSize(sampleRate, channelInConfig, audioFormat); try { recorder = new AudioRecord( MediaRecorder.AudioSource.MIC , sampleRate, channelInConfig, audioFormat, bufSize); @@ -508,6 +521,54 @@ public void onCompletion(MediaPlayer mp) { } } + private void playWithMediaPlayerOld() + { + File recordedFile = new File(getFilename()); + if(recordedFile.exists()) + { + if (isHeadsetConnected()) { + startBluetoothSCOAudio(true); + } + + Uri fileAsUri = null; + try { + fileAsUri = MediaFileUtils.encodePCMtoWavThenTransferFileToMediaStore(this, recordedFile, sampleRate, channelNumber, bitDepth, replayGain); + } catch (IOException e) { + Log.e(TAG, "Exception: " + e); + e.printStackTrace(); + return; + } + + MediaPlayer mediaPlayer = new MediaPlayer(); + + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + mp.stop(); + mp.release(); + if (audioManager.isBluetoothScoOn()) { + Log.w(TAG, "Stop play Disconnect BTSCO play"); + startBluetoothSCOAudio(false); + } else + Log.w(TAG, "play BTSCO is not connected"); + + } + }); + try { + mediaPlayer.setDataSource(this, fileAsUri); + mediaPlayer.setAudioStreamType(AudioManager.STREAM_VOICE_CALL); + mediaPlayer.prepare(); + mediaPlayer.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + else + { + Toast.makeText(this, "No recorded data found.", Toast.LENGTH_SHORT).show(); + } + } + private boolean isHeadsetConnected() { boolean hasConnectedDevice = false; AudioDeviceInfo[] devices = audioManager.getDevices(AudioManager.GET_DEVICES_OUTPUTS); @@ -583,8 +644,6 @@ private void playPcmFileWithAudioTrack(boolean manualGain) { routeAudioToHeadset(true); } - - AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_MEDIA) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) @@ -635,7 +694,7 @@ private void playPcmFileWithAudioTrack(boolean manualGain) { private void checkIfZebraDeviceToGrantAllPermissions() { - if(Build.MANUFACTURER.toLowerCase().contains("zebra")) { + if(Build.MANUFACTURER.toLowerCase().contains("zebra") && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { CriticalPermissionsHelper.grantPermission(this, EPermissionType.ALL_DANGEROUS_PERMISSIONS, new IResultCallbacks() { @Override public void onSuccess(String message, String resultXML) { @@ -720,7 +779,8 @@ private void requestBluetoothPermission() } private void checkAndRequestPermissions() { - String[] permissions = { + + String[] permissions = new String[]{ Manifest.permission.MODIFY_AUDIO_SETTINGS, Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH_CONNECT, @@ -760,8 +820,8 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in } if(allgranted == false) { - Toast.makeText(this, "Please accept permissions", Toast.LENGTH_LONG).show(); - checkAndRequestPermissions(); + Toast.makeText(this, "Please accept all permissions", Toast.LENGTH_LONG).show(); + checkIfZebraDeviceToGrantAllPermissions(); } else { @@ -769,4 +829,33 @@ public void onRequestPermissionsResult(int requestCode, String[] permissions, in } } } + + private void activateMaximumAudioProfile() + { + if(emdkUtils == null) { + emdkUtils = new EMDKUtils(this); + emdkUtils.activateVolumeProfile("MAXIMUM", new EMDKUtils.IResultCallbacks() { + @Override + public void onSuccess(String message, String resultXML) { + Toast.makeText(MainActivity.this, "Profile applied with success", Toast.LENGTH_LONG).show(); + emdkUtils = null; + } + + @Override + public void onError(String message, String resultXML) { + Toast.makeText(MainActivity.this, "Error applying profile.\nCheck logcat.", Toast.LENGTH_LONG).show(); + emdkUtils = null; + } + + @Override + public void onDebugStatus(String message) { + + } + }); + } + else + { + Toast.makeText(MainActivity.this, "Activate MAXIMUM audio profile/n is already running", Toast.LENGTH_SHORT).show(); + } + } } diff --git a/hsdemo/src/main/res/layout/activity_main.xml b/hsdemo/src/main/res/layout/activity_main.xml index e511005..2f892ed 100644 --- a/hsdemo/src/main/res/layout/activity_main.xml +++ b/hsdemo/src/main/res/layout/activity_main.xml @@ -1,5 +1,5 @@ - + + +