有点奇怪!
我有大量Android(4.4.2)设备运行一些自定义传送跟踪软件(我写的) - 其中一项功能是录制语音报告并通过移动网络发送。它通常都工作得非常出色,但是我已经购买了一些新设备,突然所有的录音都以50kb的大小和0:00的长度进行。
现在,每个数据包都使用JSON进行编码,并通过XMPP(通过OpenFire)发送到用VB.NET编写的XMPP bot客户端(使用jabber) - 下面显示了一个示例数据包(我省略了一些,到期)它的长度,但你会得到一般的想法):
{"mMessageType":{"batteryInfo":{"mHealth":2,"mLevel":84,
"mPlugged":2,"mStatus":2,"mTemp":318},"content":"VOICE",
"mType":"VOICE","userId":406},"mPayload":{"data":[0,0,0,24,
102,116,121,112,51,103,112,52,0,0,0,0,105,115,111,109,51,103,
112,52,0,0,5,8,109,111,111,118,0,0,0,108,109,118,104,100,0,
0,0,0,-49,-68,-88,-64,-49,-68,-88,-64,0,0,3,-24,0,0,14,36,0,
1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,27,117,100,116,97,
0,0,0,19,97,117,116,104,0,0,0,0,21,-57,76,71,69,0,47,0,0,4,
121,116,114,97,107,0,0,0,92,116,107,104,100,0,0,0,7,-49,-68,
-88,-64,-49,-68,-88,-64,0,0,0,1,0,0,0,0,0,0,14,36,0,0,0,0,0,
0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,4,21,
109,100,105,97,0,0,0,32,109,100,104,100,0,0,0,0,-49,-68,-88,
-64,-49,-68,-88,-64,0,0,31,64,0,0,113,32,0,0,0,0,0,0,0,44,
104,100,108,114,0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,
0,0,0,0,0,0,83,111,117,110,100,72,97,110,100,108,101,0,0,0,
3,-63,109,105,110,102,0,0,0,16,115,109,104,100,0,0,0,0,0,0,
0,0,0,0,0,36,100,105,110,102,0,0,0,28,100,114,101,102,0,0,0,
0,0,0,0,1,0,0,0,12,117,114,108,32,0,0,0,1,0,0,3,-123,115,
116,98,108,0,0,0,69,115,116,115,100,0,0,0,0,0,0,0,1,0,0,0,
53,115,97,109,114,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,16,
0,0,0,0,31,64,0,0,0,0,0,17,100,97,109,114,32,32,32,0,0,
-125,-1,0,1,0,0,0,32,115,116,116,115,0,0,0,0,0,0,0,2,0,0,0,
1,0,0,0,-96,0,0,0,-76,0,0,0,-96,0,0,2,-24,115,116,115,122,0,
0,0,0,0,0,0,0,0,0,0,-75,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,
0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,32,0,0,0,
... Removed for sanity sake
,96],"timestamp":"","path":"/storage/emulated/0/audio_85344_1.3gp",
"reportedFully":0,"deliverySiteId":85344,"id":17,"reported":1}}
这是在这里输入我的.NET客户端:
Public Sub ProcessVoiceMessage(ByVal o As Message)
Dim messageObject = JsonConvert.DeserializeObject(Of Transaction)(o.Body)
' Incoming Message
WriteToLog(o.From.User & "/" & o.From.Resource, "VOICE Transaction >> Device Record ID: " &
messageObject.mPayload("id") & " - for DeliveryID: " & messageObject.mPayload("deliverySiteId"))
Dim i As Long = 0
Dim audioBytes(1024 * 50) As Byte
For Each jval As JValue In messageObject.mPayload("data")
Dim byteseses(1024 * 2) As Byte
byteseses = BitConverter.GetBytes(jval.Value)
audioBytes(i) = byteseses(0)
i += 1
Next
Dim fn As String = IO.Path.Combine(IO.Path.GetTempPath, IO.Path.GetTempFileName & ".mp3")
File.WriteAllBytes(fn, audioBytes)
' See if this payload is linked to a delivery drop, or that of a device level recording
' (in which case, we save against the device object itself)
If (CLng(messageObject.mPayload("deliverySiteId")) > 0) Then
Dim ds As New DeliverySite(CLng(messageObject.mPayload("deliverySiteId")))
ds.AddDocument(fn, GlobalStoreDocument.eAttachmentType.Upload, GlobalStoreDocument.eDocumentType.PODVoice, Nothing, ds.ParentDelivery.Driver.ID)
Dim mt As New MessageType(MessageType.Type.CONFIRMATION)
Dim conf As New Confirmation(ConfirmationStatus.ALL_OK,
"VOICE",
"GEE_THANKS!",
messageObject.mPayload("id"))
SendMessage(MakeTransactionPacket(mt, conf, o.From.Bare))
ds.Dispose()
ds = Nothing
mt = Nothing
conf = Nothing
Else
' Device level voice recording
Dim d As New Device(o.From.User)
d.AddDocument(fn, GlobalStoreDocument.eAttachmentType.Upload, GlobalStoreDocument.eDocumentType.PODVoice, Nothing, CLng(messageObject.mMessageType("userId")))
Dim mt As New MessageType(MessageType.Type.CONFIRMATION)
Dim conf As New Confirmation(ConfirmationStatus.ALL_OK,
"VOICE",
"GEE_THANKS!",
messageObject.mPayload("id"))
SendMessage(MakeTransactionPacket(mt, conf, o.From.Bare))
d.Dispose()
d = Nothing
mt = Nothing
conf = Nothing
End If
IO.File.Delete(fn)
messageObject = Nothing
audioBytes = Nothing
End Sub
正如我之前所说的那样,它正在发挥作用,所以我立刻就像一只疯狂的猴子一样开始劈开它......(不用担心,我是所有的SVN' d!)它&# 39;显然是从JSON数组解码字节值的问题,因此转换回二进制格式,但我无法理解它。
**编辑** 应该真的添加所有的Android代码!用于语音报告的MediaRecorder:
public void startRecording()
{
++voiceRecordingNumber;
filename = Environment.getExternalStorageDirectory().getPath();//.getAbsolutePath();
if(this.d != null)
{
// FOR DELIVERY RECORDING OF PROOF //
filename += String.format("/audio_%s_%d.%s", this.d.getDeliveryId(), voiceRecordingNumber, Constants.VOICE_EXT);
}
else
{
// FOR HOME SCREEN RECORDING OF PROOF //
filename += String.format("/audio_PROOF_%s.%s", String.valueOf(System.currentTimeMillis()), Constants.VOICE_EXT);
}
Log.i("VoiceRecorder", "Startup");
recorder.setAudioSource(MediaRecorder.AudioSource.MIC); // Default audio source
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 3GPP Media File
recorder.setOutputFile(filename); // Output filename
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // audio codec
recorder.setAudioSamplingRate(Constants.SAMPLERATES_MPEG1_L3[0]); // Sample rate
try
{
recorder.prepare();
} catch (IllegalStateException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
Log.i("VoiceRecorder","Am prepared");
recorder.start();
}
通过xmpp发送所有数据的后台进程:
// Get a list of all voice recordings to send
List<AudioRecording> audios = new AudioRecording().getAllRecords();
for(AudioRecording a : audios)
{
// Process the audio files on local storage for sending over the wire
ByteArrayOutputStream baos = new ByteArrayOutputStream();
File audioFile = new File(a.getPath());
InputStream is = new FileInputStream(audioFile);
byte[] b = new byte[1024];
int read;
try
{
while((read = is.read(b)) >= 0)
{
baos.write(b, 0, read);
}
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
byte[] data = baos.toByteArray();
a.setData(data);
Log.i("BGCP", "Processing voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ")");
Intent intent = new Intent(getApplicationContext(), BackgroundXmppConnector.class);
intent.putExtra("MESSAGEDATA", new Gson().toJson(
Utility.makeTransaction(getApplicationContext(),
MessageType.Type.VOICE,
a)));
if(mService.sendMessage(intent))
{
Log.i("BGCP", "Voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ") HAS been reported");
a.setReported(1);
a.updateRecord();
}
else
{
Log.i("BGCP", "Voice transaction (" + a.getId() + "/" + a.getDeliverySiteId() + ") HAS NOT been reported");
// Ignore the updating of this record, it'll get sent out when we spin in 1 minute
}
b = null;
is = null;
data = null;
baos = null;
intent = null;
audioFile = null;
}
非常感谢任何帮助。谢谢!
答案 0 :(得分:0)
通过将字节数组转换为Base64字符串并将其发送出去来解决此问题。解码现在变得更加容易:
Dim ms As MemoryStream = GetVoiceRecordingFromString(messageObject.mPayload("dataAsString"))
File.WriteAllBytes(fn, ms.ToArray())
方法
Public Function GetVoiceRecordingFromString(ByVal s As String) As MemoryStream
If s = "" Then
Return Nothing
End If
Dim b As Byte() = Convert.FromBase64String(s)
Using ms As MemoryStream = New MemoryStream(b, 0, b.Length)
ms.Write(b, 0, b.Length)
Return ms
End Using
End Function