編輯:關於Android編程
RakNet在Win平台上已經實現消息、語音、文件傳輸了,但在Android平台下尚未實現,筆者決定把源碼移植到Android平台下測試。
項目自帶Chat Example Client和Chat Example Server實現消息,源碼簡單易懂,此處就不介紹了,直接貼上圖片。
vcq9z9TKvrXEo6zNvMaszrSytte9tb3P1Mq+oaM8L3A+PGg1Psq1z9bT79L0PC9oNT48cD5XaW7Gvcyoz8LKtc/W0+/S9MrHzai5/VBvcnRhdWRpb7340NC1xKOsUG9ydGF1ZGlvydDOtNans9ZBbmRyb2lko6zSqsq1z9bT79L01PXDtLDso788L3A+PHA+SmF2YbLjyrXP1r/J0tSjrLWrscrV3771tcPC6bezo6y+9rao0sbWslBvcnRhdWRpb7W9QW5kcm9pZKGjudjT2tXit73D5rXE0MXPosfrsum/tLKpv82jukFuZHJvaWQgUmFrTmV0IM+1wdDWrsj9INLG1rJQb3J0YXVkaW+hozwvcD48cD7Ktc/W1K3A7aO6UmFrbmV0zai5/VBvcnRBdWRpb7340NDT79L0ssm8r9LUvLCypbfFo6zU2c2ouf1SYWtWb2ljZdPv0vSy5bz+vfjQ0NPv0vS3osvN0+u908rco6xSYWtWb2ljZdbQyrnTw8HLc3BlZXix4MLrtKvK5KGjPC9wPjxwPkpuacq1z9bW99KqtPrC68jnz8KjujwvcD48cD48L3A+PHByZSBjbGFzcz0="brush:java;">class Voice { //聲音一個操作語音的類 public: Voice(); virtual ~Voice(); void run(const char* ip); //關鍵執行 int portInAudioCallback(const void *inputBuffer); int portOutAudioCallback(void *inputBuffer); void waitForStop(); void stop(); public: bool mute; RakNet::RakPeerInterface *rakPeer; RakNet::RakVoice rakVoice; PaError err; bool isStoped; bool runState; };
void Voice::run(const char* ip) { //通過Ip連接對方機子,然後傳輸。 //////////////////////////////////////////// if (err != paNoError) { LOGI("Pa_Initialize fail: %s",Pa_GetErrorText(err)); return; } mute = false; PaStream *stream; unsigned int maxConnectionsAllowed = 4; unsigned int maxPlayersPerServer = 4; unsigned short serverPort = 6000; RakNet::SocketDescriptor socketDescriptor(serverPort, 0); if (rakPeer->Startup(maxConnectionsAllowed, &socketDescriptor, 1) != RakNet::RAKNET_STARTED) { LOGI("Startup fail:"); return; } rakPeer->SetMaximumIncomingConnections(maxPlayersPerServer); rakPeer->AttachPlugin(&rakVoice); rakVoice.Init(SAMPLE_RATE, FRAMES_PER_BUFFER * sizeof (short)); PaDeviceIndex numdev; const PaDeviceInfo *info; int i; numdev = Pa_GetDeviceCount(); PaStreamParameters inparam, outparam; memset(&inparam, 0, sizeof (PaStreamParameters)); inparam.device = Pa_GetDefaultInputDevice(); inparam.channelCount = 1; inparam.sampleFormat = paInt16; memset(&outparam, 0, sizeof (PaStreamParameters)); outparam.device = Pa_GetDefaultOutputDevice(); outparam.channelCount = 1; outparam.sampleFormat = paInt16; PaError err = Pa_OpenStream(&stream, &inparam, &outparam, SAMPLE_RATE, FRAMES_PER_BUFFER, paClipOff, PAInOutCallback, this); err = Pa_SetStreamFinishedCallback(stream, &StreamFinished ); if(err != paNoError){ LOGI("Cannot set stream finish callback"); return; } if (err != paNoError) { LOGI("Pa_OpenStream fail: %s",Pa_GetErrorText(err)); return; } err = Pa_StartStream(stream); if (err != paNoError) { LOGI("Pa_StartStream fail: %s",Pa_GetErrorText(err)); return; } if (ip) { LOGI("Connect: %s",ip); rakPeer->Connect(ip, serverPort, 0, 0); } RakNet::Packet *p; unsigned char typeId; isStoped = false; runState = true; while (1) { if(!runState) { Pa_AbortStream(stream); Pa_CloseStream(stream); isStoped = true; return; } p=rakPeer->Receive(); while (p) { LOGI("Receive data from: %s guid",p->systemAddress.ToString(),p->guid.ToString()); if (p->data[0]==ID_CONNECTION_REQUEST_ACCEPTED) { LOGI("ID_CONNECTION_REQUEST_ACCEPTED from %s\n", p->systemAddress.ToString()); rakVoice.RequestVoiceChannel(p->guid); } else if (p->data[0]==ID_CONNECTION_ATTEMPT_FAILED) { LOGI("ID_CONNECTION_ATTEMPT_FAILED\n"); } else if (p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REQUEST || p->data[0]==ID_RAKVOICE_OPEN_CHANNEL_REPLY) { LOGI("Got new channel from %s\n", p->systemAddress.ToString()); } else if (p->data[0]==ID_NAT_TARGET_NOT_CONNECTED) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); LOGI("ID_NAT_TARGET_NOT_CONNECTED for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_TARGET_UNRESPONSIVE) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); LOGI("ID_NAT_TARGET_UNRESPONSIVE for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_CONNECTION_TO_TARGET_LOST) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); LOGI("ID_NAT_CONNECTION_TO_TARGET_LOST for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_ALREADY_IN_PROGRESS) { RakNet::RakNetGUID g; RakNet::BitStream b(p->data, p->length, false); b.IgnoreBits(8); // Ignore the ID_... b.Read(g); LOGI("ID_NAT_ALREADY_IN_PROGRESS for %s\n", g.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_FAILED) { LOGI("ID_NAT_PUNCHTHROUGH_FAILED for %s\n", p->guid.ToString()); } else if (p->data[0]==ID_NAT_PUNCHTHROUGH_SUCCEEDED) { LOGI("ID_NAT_PUNCHTHROUGH_SUCCEEDED for %s. Connecting...\n", p->guid.ToString()); rakPeer->Connect(p->systemAddress.ToString(false),p->systemAddress.GetPort(),0,0); } else if (p->data[0]==ID_ALREADY_CONNECTED) { LOGI("ID_ALREADY_CONNECTED\n"); } else if (p->data[0]==ID_RAKVOICE_CLOSE_CHANNEL) { LOGI("ID_RAKVOICE_CLOSE_CHANNEL\n"); } else if (p->data[0]==ID_DISCONNECTION_NOTIFICATION) { LOGI("ID_DISCONNECTION_NOTIFICATION\n"); } else if (p->data[0]==ID_NEW_INCOMING_CONNECTION) { LOGI("ID_NEW_INCOMING_CONNECTION\n"); } else if(p->data[0]==ID_CONNECTION_LOST) { LOGI("ID_CONNECTION_LOST 可靠的數據包不能被傳遞到指定的分組系統"); } else { LOGI("Unknown packet ID %i\n", p->data[0]); } rakPeer->DeallocatePacket(p); p=rakPeer->Receive(); } Pa_Sleep( 30 ); } }
效果如圖:
class CBTransferInterface : public RakNet::FileListTransferCBInterface //傳輸文件接口 { public: bool OnFile(OnFileStruct *onFileStruct); virtual void OnFileProgress(FileProgressStruct *fps); virtual bool OnDownloadComplete(DownloadCompleteStruct *dcs); }; // Sender progress notification class TestFileListProgress : public RakNet::FileListProgress //進度通知 { virtual void OnFilePush(const char *fileName, unsigned int fileLengthBytes, unsigned int offset, unsigned int bytesBeingSent, bool done, RakNet::SystemAddress targetSystem, unsigned short setID); virtual void OnFilePushesComplete( RakNet::SystemAddress systemAddress, unsigned short setID ); virtual void OnSendAborted( RakNet::SystemAddress systemAddress ); }; class FileTransferClient //客戶端 { public: int testTransfer(const char* ip,const char* filePath); void stopTransfer(); void waitForStop(); public: int transferStatus; int isStoped; };
1.RxJava概述ReactiveX與RxJava在講到RxJava之前我們首先要了解什麼是ReactiveX,因為RxJava是ReactiveX的一種java實現。
Android開發四大組件分別是:活動(Activity):用於表現功能。服務(Service):後台運行服務,不提供界面呈現。廣播接收器(BroadcastReceiv
1.總結之前學習的關於屬性動畫的筆記 和 學習了郭霖大神的 屬性動畫高級用法相關的博客之後的記錄2.學習loading… 2.1補間動畫 PK 屬性動畫在篇
本菜開源的一個自己寫的Demo,希望能給Androider們有所幫助,水平有限,見諒見諒.. https://github.com/zhiaixinyang/MyFir