如何用Wowza Gocoder SDK Android版開發一個基本功能的直播APP?

2021-02-15 哲想軟體

這篇文章介紹了如何用Wowza Gocoder SDK Android版開發一個基本功能的直播APP。

一、創建一個新的開發項目


首先你需要在Android Studio中創建一個APP開發項目。 

打開Android     Studio,在 Welcome to Android Studio 窗口點擊 Start     a New Android Studio Project

在 Create     New Project 窗口中的 New Project 界面上點擊 Edit 編輯 Package     Name 的名字。     然後輸入在生成SDK License Key時提交的應用類包名,然後點擊 Next 

在 project     options的對話框中,輸入 Product Name 和 Organization     Name 注意, Bundle     Identifier 必須與申請 license key時提交的一樣。

在 Target     Android Devices 界面,選擇APP運行的設備類型(通常是手機或者平板),選擇支持的最低系統版本API 19及以上。然後點擊 Next

在 Add     an Activity to Mobile 界面選擇 Empty Activity ,然後點擊 Next

在 Customize     the Activity 界面,接受默認設置,然後點擊 Finish

確認Gocoder     SDK 的類庫被安裝正確,並在 AndroidManifest.xml 文件中添加的權限。

 

二、添加一個直播按鈕

在這一步,你需要在APP的界面上添加一個直播按鈕. 

在Android     Studio上點擊 File ,然後點擊 Open

打開 [project_root]/app/src/main/res/layout/activity_main.xml

將下面的配置更新到 activity_main.xml 文件中,並將tools:context參數的com.mycompany.myapp替換為當前APP的 MainActivity Class

<?xml version="1.0"     encoding="utf-8"?>

<RelativeLayout

      xmlns:android="http://schemas.android.com/apk/res/android"

     xmlns:tools="http://schemas.android.com/tools"

      xmlns:wowza="http://schemas.android.com/apk/res-auto"

      android:id="@+id/activity_main"

     android:layout_width="match_parent"

  android:layout_height="match_parent"

      tools:context="com.mycompany.myapp.MainActivity">

 

  <!-- The camera     preview display -->

      <com.wowza.gocoder.sdk.api.devices.WZCameraView

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:id="@+id/camera_preview"

        wowza:scaleMode="fill"

        wowza:defaultCamera="back"

        wowza:frameSizePreset="frameSize1280x720"/>

 

  <!-- The broadcast     button -->

  <Button

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Broadcast"

        android:id="@+id/broadcast_button"

        android:layout_alignParentBottom="true"

        android:layout_centerHorizontal="true" />

 

</RelativeLayout>

          

在 [project_root]/app/src/main/AndroidManifest.xml 文件中,為 activity 元素添加 android:configChanges 參數。

<activity android:name=".MainActivity"

        android:configChanges="orientation|keyboardHidden|screenSize">

          

為 MainActivity Class添加 onWindowFocusChanged() 方法,以此來開啟Androidimmersive full-screen 模式

//

// Enable Android's sticky immersive full-screen mode

//

@Override

public void onWindowFocusChanged(boolean hasFocus) {

      super.onWindowFocusChanged(hasFocus);

 

  View rootView =     getWindow().getDecorView().findViewById(android.R.id.content);

  if (rootView != null)

        rootView.setSystemUiVisibility(

            View.SYSTEM_UI_FLAG_LAYOUT_STABLE

            | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

            |     View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

            |     View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

            |     View.SYSTEM_UI_FLAG_FULLSCREEN

            |     View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

}

 

三、定義APP的參數

在 MainActivity.java 文件中為 MainActivity Class 添加下面的成員變量:

public class MainActivity extendsAppCompatActivity {

 

   // The top level GoCoder API interface

   private WowzaGoCoder goCoder;

 

   // The GoCoder SDK camera view

   private WZCameraView goCoderCameraView;

 

   // The GoCoder SDK audio device

   private WZAudioDevice goCoderAudioDevice;

 

   // The broadcast configuration settings

   private WZBroadcastConfig goCoderBroadcastConfig;

 

   // Properties needed for Android 6+ permissions handling

    private static final intPERMISSIONS_REQUEST_CODE = 0x1;

   private boolean mPermissionsGranted = true;

   private String[] mRequiredPermissions = new String[] {

            Manifest.permission.CAMERA,

            Manifest.permission.RECORD_AUDIO

   };

 

四、註冊和初始化SDK

在這一步,你需要在 MainActivity Class的 onCreate() 方法中添加下面的代碼來註冊和初始化GoCoder SDK 的License。 
請用你的License key替換下面的 GOSK-XXXX-XXXX-XXXX-XXXX-XXXX 

// Initialize the GoCoder SDK

goCoder =WowzaGoCoder.init(getApplicationContext(), "GOSK-XXXX-XXXX-XXXX-XXXX-XXXX");

 

if (goCoder == null) {

   // If initialization failed, retrieve the last error and display it

   WZError goCoderInitError = WowzaGoCoder.getLastError();

   Toast.makeText(this,

       "GoCoder SDK error: " +goCoderInitError.getErrorDescription(),

       Toast.LENGTH_LONG).show();

   return;

}

 

五、檢查APP的權限

接下來,你必須為APP定義它所需要的權限:

在頂級的 manifest 元素下方的 [project_root]/app/src/main/AndroidManifest.xml 文件中添加下面的權限:

<?xml version="1.0"     encoding="utf-8"?>

<manifest    

xmlns:android="http://schemas.android.com/apk/res/android"

              package="com.cintimedia.foobar">


   <!-- Define the     required application permissions -->

    <uses-permission     android:name="android.permission.CAMERA" />

    <uses-permission     android:name="android.permission.RECORD_AUDIO" />

    <uses-permission     android:name="android.permission.INTERNET" />

    <uses-permission     android:name="android.permission.FLASHLIGHT" />

 

    <uses-permission     android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

            

對於Android     6.0及以上版本,你需要在 MainActivity class中添加 onResume() 和 onRequestPermissionsResult() 方法來檢查用戶已經授權APP來訪問攝像頭和麥克風。

//

// Called when an activity is brought to the foreground

//

@Override

protected void onResume() {

    super.onResume();

 

    // If running on     Android 6 (Marshmallow) or above, check to see if the necessary     permissions

    // have been granted

    if     (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

            mPermissionsGranted = hasPermissions(this, mRequiredPermissions);

        if (!mPermissionsGranted)

                ActivityCompat.requestPermissions(this, mRequiredPermissions,     PERMISSIONS_REQUEST_CODE);

    } else

            mPermissionsGranted = true;

 

}

 

//

// Callback invoked in response to a call to     ActivityCompat.requestPermissions() to interpret

// the results of the permissions request

//

@Override

public void onRequestPermissionsResult(int requestCode, String     permissions[], int[] grantResults) {

    mPermissionsGranted =     true;

    switch (requestCode)     {

        case PERMISSIONS_REQUEST_CODE:     {

            // Check the     result of each permission granted

            for(int     grantResult : grantResults) {

                if     (grantResult != PackageManager.PERMISSION_GRANTED) {

                        mPermissionsGranted = false;

                }

            }

        }

    }

}

 

//

// Utility method to check the status of a permissions request     for an array of permission identifiers

//

private static boolean hasPermissions(Context context, String[]     permissions) {

    for(String permission     : permissions)

        if     (context.checkCallingOrSelfPermission(permission) !=     PackageManager.PERMISSION_GRANTED)

            return false;

 

    return true;

}

                  

 

六、開啟攝像頭預覽

接下來,我們需要配置和開啟攝像頭預覽:

在 MainActivity Class的 onCreate() 方法中添加下面的代碼,將在activity的layout中定義的視圖(view) WZCameraView 關聯起來,並創建一個音頻輸入設備實例。

// Associate the WZCameraView defined in the U/I layout with     the corresponding class member

goCoderCameraView = (WZCameraView)     findViewById(R.id.camera_preview);

 

// Create an audio device instance for capturing and     broadcasting audio

goCoderAudioDevice = new WZAudioDevice();

                  

在 Main     Activity Class的 onResume() 方法的最後面添加以下代碼(在權限檢查邏輯之後),當APP喚醒到前臺時,來開啟攝像頭預覽

// Start the camera preview display

if (mPermissionsGranted && goCoderCameraView != null) {

    if     (goCoderCameraView.isPreviewPaused())

            goCoderCameraView.onResume();

    else

           goCoderCameraView.startPreview();       

}

      

七、配置直播相關參數

在 MainActivity Class的 onCreate 方法中加入對直播的相關參數,包括伺服器地址(hostAddress)、埠(portNumber)應用名(applicationName)和流名(streamName)。這個伺服器不限於Wowza Streaming Engine或Wowza Streaming Cloud。 
如果你要往Wowza Streaming Cloud 雲平臺推流,那麼你可以在Wowza Streaming Cloud的Web界面的live streaming詳情的 Overview Tab頁上找到 Connection Code 

// Get a copy of the active config

WowzaConfig *goCoderBroadcastConfig =self.goCoder.config;

 

// Set the defaults for 720p video

[goCoderBroadcastConfigloadPreset:WZFrameSizePreset1280x720];

 

// Set the connection properties for thetarget Wowza Streaming Engine server or Wowza Cloud account

goCoderBroadcastConfig.hostAddress =@"live.someserver.net";

goCoderBroadcastConfig.portNumber =1935;

goCoderBroadcastConfig.applicationName =@"live";

goCoderBroadcastConfig.streamName =@"myStream";

 

// Update the active config

self.goCoder.config =goCoderBroadcastConfig;

  

八、添加流傳輸的狀態回調

在這一步,我們添加對流傳輸狀態監控的回調。 
1
、我們首先要在primary activity( MainActivity )添加WZStatusCallback接口,用來對直播流的傳輸做狀態監控:

// Main app activity class

public class MainActivity extends AppCompatActivity

   implements WZStatusCallback {

   

2、在 MainActivity Class中添加WZStatusCallback接口中定義的方法:

//

// The callback invoked upon changes tothe state of the steaming broadcast

//

@Override

public void onWZStatus(final WZStatusgoCoderStatus) {

 // A successful status transition has beenreported by the GoCoder SDK

 final StringBuffer statusMessage = newStringBuffer("Broadcast status: ");

 

 switch (goCoderStatus.getState()) {

 case WZState.STARTING:

  statusMessage.append("Broadcast initialization");

  break;

 

 case WZState.READY:

  statusMessage.append("Ready to begin streaming");

  break;

 

 case WZState.RUNNING:

  statusMessage.append("Streaming is active");

  break;

 

 case WZState.STOPPING:

  statusMessage.append("Broadcast shutting down");

  break;

 

 case WZState.IDLE:

  statusMessage.append("The broadcast is stopped");

  break;

 

 default:

  return;

 }

 

 // Display the status message using the U/Ithread

 new Handler(Looper.getMainLooper()).post(newRunnable() {

 @Override

 public void run() {

  Toast.makeText(MainActivity.this, statusMessage,Toast.LENGTH_LONG).show();

 }

 });

}

 

//

// The callback invoked when an erroroccurs during a broadcast

//

@Override

public void onWZError(final WZStatusgoCoderStatus) {

 // If an error is reported by the GoCoder SDK,display a message

 // containing the error details using the U/Ithread

 new Handler(Looper.getMainLooper()).post(newRunnable() {

 @Override

 public void run() {

  Toast.makeText(MainActivity.this,

  "Streaming error: " +goCoderStatus.getLastError().getErrorDescription(),

  Toast.LENGTH_LONG).show();

 }

 });

}

 

九、開始直播

在開始直播之前,您還需要為直播按鈕加上啟動和停止直播的代碼: 

在 MainActivity Class中添加 View.onClickListener 接口:

// Main app activity class

public class MainActivity extends AppCompatActivity

  implements  WZStatusCallback, View.OnClickListener      {

       

在 MainActivity Class的 onCreate() 方法的最底部,它在直播按鈕被按下時被調用:

//

// The callback invoked when the broadcast button is pressed

//

@Override

public void onClick(View view) {

  // return if the user      hasn't granted the app the necessary permissions

  if      (!mPermissionsGranted) return;

 

  // Ensure the minimum      set of configuration settings have been specified necessary to

  // initiate a      broadcast streaming session

  WZStreamingError      configValidationError = goCoderBroadcastConfig.validateForBroadcast();

 

  if      (configValidationError != null) {

    Toast.makeText(this,      configValidationError.getErrorDescription(), Toast.LENGTH_LONG).show();

  } else if      (goCoderBroadcaster.getStatus().isRunning()) {

    // Stop the      broadcast that is currently running

         goCoderBroadcaster.endBroadcast(this);

  } else {

    // Start streaming

         goCoderBroadcaster.startBroadcast(goCoderBroadcastConfig, this);

  }

}   

     

在 MainActivity Class的 onCreate() 方法中添加下面的代碼將 onClick() 事件處理和activity      layout中定義的直播按鈕關聯上,

// Associate the onClick() method as the callback for the      broadcast button's click event

Button broadcastButton = (Button) findViewById(R.id.broadcast_button);

broadcastButton.setOnClickListener(this);

 

十、構建和運行你的APP

最後,可以編譯和測試的APP了,請點擊 Run 菜單,選擇 Run 或者 Debug 。 

十一、MainActivity的例子程序

下面是一個完整的 MainActivity Class的例子,代碼包括上面講到的所有內容:

public class MainActivity extendsAppCompatActivity

 implements WZStatusCallback, View.OnClickListener {

 

 // The top level GoCoder API interface

 private WowzaGoCoder goCoder;

 

 // The GoCoder SDK camera view

 private WZCameraView goCoderCameraView;

 

 // The GoCoder SDK audio device

 private WZAudioDevice goCoderAudioDevice;

 

 // The GoCoder SDK broadcaster

 private WZBroadcast goCoderBroadcaster;

 

 // The broadcast configuration settings

 private WZBroadcastConfig goCoderBroadcastConfig;

 

 // Properties needed for Android 6+ permissions handling

 private static final int PERMISSIONS_REQUEST_CODE = 0x1;

 private boolean mPermissionsGranted = true;

 private String[] mRequiredPermissions = new String[] {

   Manifest.permission.CAMERA,

   Manifest.permission.RECORD_AUDIO

 };

 

 @Override

 protected void onCreate(Bundle savedInstanceState) {

 super.onCreate(savedInstanceState);

 setContentView(R.layout.activity_main);

 

 // Initialize the GoCoder SDK

 goCoder = WowzaGoCoder.init(getApplicationContext(),"GOSK-XXXX-XXXX-XXXX-XXXX-XXXX");

 

 if (goCoder == null) {

   // If initialization failed, retrieve the last error and display it

   WZError goCoderInitError = WowzaGoCoder.getLastError();

   Toast.makeText(this,

     "GoCoder SDK error: " +goCoderInitError.getErrorDescription(),

     Toast.LENGTH_LONG).show();

   return;

 }

 

 // Associate the WZCameraView defined in the U/I layout with thecorresponding class member

 goCoderCameraView = (WZCameraView) findViewById(R.id.camera_preview);

 

 // Create an audio device instance for capturing and broadcasting audio

 goCoderAudioDevice = new WZAudioDevice();

 

 // Create a broadcaster instance

 goCoderBroadcaster = new WZBroadcast();

 

 // Create a configuration instance for the broadcaster

  goCoderBroadcastConfig= new WZBroadcastConfig(WZMediaConfig.FRAME_SIZE_1920x1080);

 

 // Set the connection properties for the target Wowza Streaming Engineserver or Wowza Cloud account

 goCoderBroadcastConfig.setHostAddress("live.someserver.net");

 goCoderBroadcastConfig.setPortNumber(1935);

 goCoderBroadcastConfig.setApplicationName("live");

 goCoderBroadcastConfig.setStreamName("myStream");

 

 // Designate the camera preview as the video broadcaster

 goCoderBroadcastConfig.setVideoBroadcaster(goCoderCameraView);

 

 // Designate the audio device as the audio broadcaster

 goCoderBroadcastConfig.setAudioBroadcaster(goCoderAudioDevice);

 

 // Associate the onClick() method as the callback for the broadcastbutton's click event

 Button broadcastButton = (Button) findViewById(R.id.broadcast_button);

 broadcastButton.setOnClickListener(this);

 }

 

 //

 // Called when an activity is brought to the foreground

 //

 @Override

 protected void onResume() {

 super.onResume();

 

 // If running on Android 6 (Marshmallow) or above, check to see if thenecessary permissions

 // have been granted

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

   mPermissionsGranted = hasPermissions(this, mRequiredPermissions);

   if (!mPermissionsGranted)

   ActivityCompat.requestPermissions(this, mRequiredPermissions,PERMISSIONS_REQUEST_CODE);

 } else

   mPermissionsGranted = true;

 

 // Start the camera preview display

 if (mPermissionsGranted && goCoderCameraView != null) {

   if (goCoderCameraView.isPreviewPaused())

   goCoderCameraView.onResume();

   else

   goCoderCameraView.startPreview();

 }

 

 }

 

 //

 // Callback invoked in response to a call toActivityCompat.requestPermissions() to interpret

 // the results of the permissions request

 //

 @Override

 public void onRequestPermissionsResult(int requestCode, Stringpermissions[], int[] grantResults) {

 mPermissionsGranted = true;

 switch (requestCode) {

   case PERMISSIONS_REQUEST_CODE: {

   // Check the result of each permission granted

   for(int grantResult : grantResults) {

     if (grantResult != PackageManager.PERMISSION_GRANTED) {

     mPermissionsGranted = false;

     }

   }

   }

 }

 }

 

 //

 // Utility method to check the status of a permissions request for anarray of permission identifiers

 //

 private static boolean hasPermissions(Context context, String[]permissions) {

 for(String permission : permissions)

   if (context.checkCallingOrSelfPermission(permission) !=PackageManager.PERMISSION_GRANTED)

   return false;

 

 return true;

 }

 

 //

 // The callback invoked when the broadcast button is pressed

 //

 @Override

 public void onClick(View view) {

  //return if the user hasn't granted the app the necessary permissions

 if (!mPermissionsGranted) return;

 

 // Ensure the minimum set of configuration settings have been specifiednecessary to

 // initiate a broadcast streaming session

 WZStreamingError configValidationError =goCoderBroadcastConfig.validateForBroadcast();

 

 if (configValidationError != null) {

   Toast.makeText(this, configValidationError.getErrorDescription(),Toast.LENGTH_LONG).show();

 } else if (goCoderBroadcaster.getStatus().isRunning()) {

   // Stop the broadcast that is currently running

   goCoderBroadcaster.endBroadcast(this);

 } else {

   // Start streaming

   goCoderBroadcaster.startBroadcast(goCoderBroadcastConfig, this);

 }

 }

 

 //

 // The callback invoked upon changes to the state of the steamingbroadcast

 //

 @Override

 public void onWZStatus(final WZStatus goCoderStatus) {

 // A successful status transition has been reported by the GoCoder SDK

 final StringBuffer statusMessage = new StringBuffer("Broadcaststatus: ");

 

 switch (goCoderStatus.getState()) {

   case WZState.STARTING:

   statusMessage.append("Broadcast initialization");

   break;

 

   case WZState.READY:

   statusMessage.append("Ready to begin streaming");

   break;

 

   case WZState.RUNNING:

   statusMessage.append("Streaming is active");

   break;

 

   case WZState.STOPPING:

   statusMessage.append("Broadcast shutting down");

   break;

 

   case WZState.IDLE:

   statusMessage.append("The broadcast is stopped");

   break;

 

   default:

   return;

 }

 

 // Display the status message using the U/I thread

 new Handler(Looper.getMainLooper()).post(new Runnable() {

   @Override

   public void run() {

   Toast.makeText(MainActivity.this, statusMessage,Toast.LENGTH_LONG).show();

   }

 });

 }

 

 //

 // The callback invoked when an error occurs during a broadcast

 //

 @Override

 public void onWZError(final WZStatus goCoderStatus) {

 // If an error is reported by the GoCoder SDK, display a message

 // containing the error details using the U/I thread

 new Handler(Looper.getMainLooper()).post(new Runnable() {

   @Override

   public void run() {

   Toast.makeText(MainActivity.this,

     "Streaming error: " +goCoderStatus.getLastError().getErrorDescription(),

     Toast.LENGTH_LONG).show();

   }

 });

 }

 

  //

  // Enable Android's sticky immersive full-screen mode

  //

 @Override

 public void onWindowFocusChanged(boolean hasFocus) {

 super.onWindowFocusChanged(hasFocus);

 

 View rootView =getWindow().getDecorView().findViewById(android.R.id.content);

 if (rootView != null)

   rootView.setSystemUiVisibility(

     View.SYSTEM_UI_FLAG_LAYOUT_STABLE

       | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

       | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

       | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION

       | View.SYSTEM_UI_FLAG_FULLSCREEN

       | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);

 }

 

}

 

Wowza Streaming Engine 4是業界功能強大、API接口豐富的流媒體Server產品,採用它作為流媒體伺服器產品的案例很多,直播、在線教育、IPTV都有它的用武之地。 

 

公司名稱:北京哲想軟體有限公司

北京哲想軟體官方網站:www.cogitosoft.com

北京哲想軟體微信公眾平臺帳號:cogitosoftware

北京哲想軟體微博:哲想軟體

北京哲想軟體郵箱:sales@cogitosoft.com

銷售(俞先生)聯繫方式:+86(010)68421378

微信:18610247936     QQ:368531638

相關焦點

  • 聲網 SDK 接入以及音視頻通話應用開發指南
    當項目創建完成後就有了對應的 APP ID ,這個在後續代碼開發中會用到的。除此之外,我們還需要生成 Token ,在項目管理頁去生成一個臨時 Token 。這個臨時 Token 是有時效的,僅供測試使用,如果有自己的後端開發,到生產環境再去生成正式 Token。同樣,這個 Token 字符串在後續開發中也會用到的。3.
  • Android DropBox SDK漏洞(CVE-2014-8889)分析
    原文見http://www.slideshare.net/ibmsecurity/remote-exploitation-of-the-dropbox-sdk-for-android如今個人數據存儲在雲端,這使得像照片備份或通用存儲那樣的服務不僅可以被用戶訪問,也能被代表用戶的app所訪問。
  • Android-支付寶支付開發流程
    下載支付寶SDK支付寶業務眾多,真想找到想要的支付sdk還是要費一番功夫的,這裡給出sdk地址:https://docs.open.alipay.com/54/104509(注意的是下載出來的SDK包裡面並沒有傳說中的開發文檔,需要其他地方找或者看網頁上的)想要接入支付寶行動支付功能,必須在支付寶商家服務平臺進行申請與審核。
  • 如何使用Python程式語言開發一款App
    來源:https://blog.csdn.net/nmask我很早之前就想開發一款app玩玩,無奈對java不夠熟悉,之前也沒有開發app的經驗,因此一直耽擱了。最近想到嘗試用python開發一款app,google搜索了一番後,發現確實有路可尋,目前也有了一些相對成熟的模塊,於是便開始了動手實戰,過程中發現這其中有很多坑,好在最終依靠google解決了,因此小記一番。
  • Android 遊戲開發速遞
    從遊戲開發者表現出的興趣水平以及開發者預覽版中提供的大量反饋,我們很高興能夠與各位分享我們在這些工具等方面所取得的進步。https://developer.android.google.cn/games/preview請閱讀本文詳細了解相關更新資訊。
  • 利用Python開發App
    app玩玩,無奈對java不夠熟悉,之前也沒有開發app的經驗,因此一直耽擱了。最近想到嘗試用python開發一款app,google搜索了一番後,發現確實有路可尋,目前也有了一些相對成熟的模塊,於是便開始了動手實戰,過程中發現這其中有很多坑,好在最終依靠google解決了,因此小記一番。準備工作利用python開發app需要用到python的一個模塊–kivy,kivy是一個開源的,跨平臺的Python開發框架,用於開發使用創新的應用程式。
  • Python 也能開發 App ?
    我很早之前就想開發一款app玩玩,無奈對java不夠熟悉,之前也沒有開發app的經驗,因此一直耽擱了。最近想到嘗試用python開發一款app,google搜索了一番後,發現確實有路可尋,目前也有了一些相對成熟的模塊,於是便開始了動手實戰,過程中發現這其中有很多坑,好在最終依靠google解決了,因此小記一番。
  • 如何開發一流的 Android SDK: Fabric SDK 的創建經驗
    顯然,如果一個 SDK 有一個嚴重的 bug,它的修復更新到達時間要長得多。這可能需要幾個月,用你的SDK應用程式的用戶才能得到錯誤修正。應用程式開發人員可能需要數周才能注意或升級您的 SDK 版本,並進行修復、測試 bug。所以說確保一個 SDK 的穩定性是我們的最高優先事項之一。作為開發人員我們可以做什麼,以確保儘可能高的穩定性?有一些事情是我們開發過程中的關鍵。
  • Android 系統如何預置 APP?
    問題1、如何將 APK 預置到 system/priv-app 裡?加入 priv-app 方法:在 Android.mk 中增加 LOCAL_PRIVILEGED_MODULE := true預置有源碼 APP預置有源碼 APP 比預置 APK 要麻煩很多,可能會涉及 jar 包和 so 庫等。
  • 利用Python開發App實戰
    我很早之前就想開發一款app玩玩,無奈對java不夠熟悉,之前也沒有開發app的經驗,因此一直耽擱了。最近想到嘗試用python開發一款app,google搜索了一番後,發現確實有路可尋,目前也有了一些相對成熟的模塊,於是便開始了動手實戰,過程中發現這其中有很多坑,好在最終依靠google解決了,因此小記一番。
  • ​Wowza技術:在CentOS系統上,如何使用Intel Quick Sync 硬體加速編碼?
    這個Intel Quick Sync Video技術將視頻處理任務分配給了一個獨佔的媒體處理單元,這樣使得視頻轉碼更加快速。這篇文章介紹了如何在CentOS7.1-1503(x86_64)系統上為Wowza Streaming Engine™ 4.4.0 (及以上版本)配置和使用Quick Sync 硬體加速技術。
  • Android TV開發總結(六)構建一個TV app的直播節目實例
    近年來,Android TV的迅速發展,傳統的有線電視受到較大的衝擊,在TV上用戶同樣也可以看到各個有線電視的直播頻道,相對於手機,這種直播節目
  • Android 通過Java sdk的方式接入OpenCv
    code小生 一個專注大前端領域的技術平臺公眾號回復Android加入安卓技術群作者:Mp5A5連結:https://www.jianshu.com/p/af430ae13ecd聲明:本文已獲Mp5A5投稿發表,轉發等請聯繫原作者授權Android
  • DJI Mobile SDK 開發教程系列
    Mobile SDK封裝了用於無人機層面的大部分功能,開發者只需調用其API接口,就能實現對無人機的操控。2、DJI UI Library同時,大疆還對大部分的核心功能進行了UI組件的封裝,開發者只需調用改組件,就可將該功能集成至應用程式中,無須進行邏輯代碼的編寫。如無人機狀態、GPS狀態、飛行高度、電池信息、拍照功能等。
  • Android OpenCV(零):OpenCV Android SDK
    ,其開源協議允許在學術研究與商業應用開發中免費使用它。OpenCV支持Windows、Linux、Mac OS、iOS與Android作業系統上的應用開發。OpenCV Android SDKOpenCV Android SDK 是OpenCV針對Android平臺提供的開發工具包。
  • xamarin開發android收集的一些工具
    OctoTree github看代碼時左邊出現項目的樹形結構chrome插件Android Asset Studio 在線製作icon的網站Android SDK Search 查看android sdk源碼的chrome插件GenymotionGenymotion是一套完整的工具,它提供了Android虛擬環境。
  • Android 開發實踐:實現17人視頻l聊天應用
    但連麥直播、在線抓娃娃、直播問答、遠程狼人殺等類型的項目卻異軍突起,成了投資人的風口,創業者的藍海和用戶的必裝App,而這些方向的項目都有一個共同的特點——都依賴視頻通話和全互動直播技術。目前有很多第三方平臺提供實時音視頻通訊服務,讓Android、iOS開發者們不用去考慮網絡延時、設備兼容等方面的問題。我們這次將試著通過聲網的SDK實現一個多人視頻通話應用。
  • Android Studio魔法手指,讓SDK集成快一點,再快一點!
    我們魔窗開發的sdk也是使用此IDE。我們魔窗是致力於做創業者最需要、最好用、最貼心的App增長工具,並為創業者構建一個去中心化的高效連接時代,解決App有機增長、生態落地和流量共享的問題!越來越多的App開始對接我們的sdk,有些客戶有不止一個App,甚至有些客戶有幾十個、幾百個App。如果他們要集成sdk的話,需要對一個個App來加代碼,確實是不小的工作量。
  • 每個Android開發者應該知道的6個SDK和API
    如果你是一個進入Android開發的Java開發人員,或者是一家想要確保團隊使用的是正確工具的初創企業CxO,那麼本文中列舉的這些SDK和API或許會非常有用。Material design support library在開發一個現代化的Android app時,我們總是希望能夠使用最新和最棒的設計組件。這通常會使你的應用程式不需要額外裝飾就可以看上去很漂亮。你可以有例如波紋的甜美效果,和如FAB這樣的新部件。並且design support library允許你在預裝棒棒糖的手機上面使用華麗的設計元素。
  • 入職三個月,遊戲SDK開發總結
    SDK(Software Development Kit)是軟體開發工具包的意思,一般我們將一部分功能單獨封裝成一個library進行開發和維護,然後將編譯產物(jar包或者aar)提供給多個項目使用,這就屬於SDK開發。常見的如短視頻SDK、推送SDK,分享SDK,以及這篇文章的重點:遊戲SDK。