• 准备工作
  • 修改MainActivity文件
  • 编写cmakelisttxt文件
  • 编写jni 实现文件


准备工作

请先阅读 Android Specific Starter Guide(安卓指定入门指南)
本文参考官方demo 然后播放一个普通的音乐文件

  • doc文档有这么一句话:

This means telling the IDE or build system where to find the fmod.jar file so it’s included in the application(这意味着 我们需要用fmod.jar去告诉系统如何调用)

  • 所以我们导入fmod.jar到项目中
  • android touch音播放流程_android touch音播放流程

  • doc文档可知道要导入下面的so库
  • android touch音播放流程_android touch音播放流程_02

  • 低等级类库
    libfmod.so 发行版本
    libfmodL.so 发行版本 且有打印开发日志
    工作室版本(必须依赖于libfmod)
    。。。。。
    我们这里拷贝libfmodL到项目中(这里我们只选择armeabi架构)
    导入jniLibs(as默认放入的地方)
  • android touch音播放流程_#include_03

  • 导入头文件inc到cpp下
  • android touch音播放流程_#include_04

  • 最后将一个音频文件放入assets中
  • android touch音播放流程_android_05


修改MainActivity文件

参考doc

android touch音播放流程_android touch音播放流程_06

  1. 从上图可知道 需要调用 FMOD.init进行初始化。
  2. activity生命结束对FMOD生命周期同步方法close
    现在我们自己写一个Activity
package com.example.fmy.selfplaymusic;

import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;

public class MainActivity extends AppCompatActivity {


    static {
        System.loadLibrary("native-lib");
    }

    //当前对象
    Context mContext;

    //要播放的音乐文件地址
    public static final String  music_path = "file:///android_asset/jaguar.wav";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //当前对象
        this.mContext = this;
        //初始化FMOD
        org.fmod.FMOD.init(this);


    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //同步FMOD的生命周期
        org.fmod.FMOD.close();
    }



    //调用fmod去播放音乐
    public native void playsMusic(String music_path);

    //点击按钮触发jni方法播放音乐
    public void onClick(View view) {


        //播放音乐
        playsMusic(music_path);

    }
}

对应布局文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.fmy.selfplaymusic.MainActivity">

    <Button
        android:id="@+id/sample_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="点击播放音乐"
        android:onClick="onClick"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

对应视图

android touch音播放流程_#include_07


编写cmakelist.txt文件

#cmake最小支持版本
cmake_minimum_required(VERSION 3.4.1)
#添加函数库
add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             src/main/cpp/native-lib.cpp )

#设置变量
set(libs "${CMAKE_SOURCE_DIR}/src/main/jniLibs")
#添加预编译so库
add_library(fmod-lib SHARED IMPORTED )
#设置预编译so库文件
set_target_properties( # Specifies the target library.
                      fmod-lib

                       # Specifies the parameter you want to define.
                       PROPERTIES IMPORTED_LOCATION

                       # Provides the path to the library you want to import.
                     "${libs}/${ANDROID_ABI}/libfmodL.so")
 #导入so的头文件 这样不写也可以 但是导入的时候需要写
 # #include"inc/xxx" 写下面这句话之后可以直接 #include"xxxx"
include_directories(  src/main/cpp/inc  )


#链接so库文件
target_link_libraries(
                       native-lib
                       #导入fmod源码
                        fmod-lib
                     )

编写jni 实现文件

#include <jni.h>

#include <iostream>
#include <fmod.hpp>
#include <unistd.h>
using namespace std;
extern  "C"//这句话别少 不然以c++编译找不到实现函数异常
点击按钮播放音乐
JNIEXPORT void JNICALL
Java_com_example_fmy_selfplaymusic_MainActivity_playsMusic(JNIEnv *env, jobject instance,
                                                           jstring music_path_) {


    //得到音乐文件地址
    const char *music_path = env->GetStringUTFChars( music_path_, 0);

    //FMOD系统对象
    FMOD::System       *system         = 0;
    //音效
    FMOD::Sound        *sound          = 0;
    //声轨
    FMOD::Channel       *channel       = 0;
    //创建对象
    FMOD::System_Create(&system);

    //初始化 系统对象最大声轨为32
    system->init(32,FMOD_INIT_NORMAL,0);

    //加载声音 如果过大建议你用FMOD_CREATESTREAM 标志
    system->createSound(music_path,FMOD_DEFAULT,0,&sound);

    //播放音乐
    system->playSound(sound,0, false,&channel);

    //开启更新通道 官方demo写了 但是我我发现不写也没事
    system->update();

    //保存声音时间
    unsigned int duration  =  0;

    //得到声音
    sound->getLength(&duration,FMOD_TIMEUNIT_MS);

    //线程休眠 以微妙 所以要转
    usleep(duration*1000);
     //释放资源
    sound->release();
    system->close();
    system->release();
    env->ReleaseStringUTFChars(music_path_, music_path);
}