--txcgb播放器
kksosoks={
 LinearLayout;
 Focusable=true,
 gravity="center";
 FocusableInTouchMode=true,
 {
 RelativeLayout,
 layout_height="fill_parent",
 background="#444444",
 gravity="top|center",
 layout_width="fill",
 ------分割线------音量条代码开始-----
 {
 LinearLayout,
 layout_width="fill",
 {TextView,
 layout_marginTop='66dp';
 textSize="16",
 text=" 音量 : 0% ",
 textColor="#27bb00",
 id="seekText",
 },
 {SeekBar,
 layout_marginTop='70dp';
 id="seekbar",
 layout_weight="1"
 },
 },
 ------分割线------音量条代码结束--最后还有点击事件-----
 {TextView,
 layout_height="wrap_content",
 text="享受平凡音质",
 textSize="25",
 gravity="center";
 layout_marginTop='95dp';
 layout_width="match_parent",
 id="tv_title",
 layout_alignParentTop=true,
 padding="10dp",
 background="#444444",
 textColor="#27bb00"},
 {ImageView,
 layout_height="wrap_content",
 layout_width="wrap_content",
 id="back",
 -- src="back",
 layout_margin="10dp",
 layout_centerHorizontal=true,
 layout_centerVertical=true
 },
 {LinearLayout,
 layout_height="wrap_content",
 layout_width="match_parent",
 orientation="vertical",
 id="mainLinearLayout1",
 gravity="bottom|center",
 layout_alignParentBottom=true,
 {TextView,
 layout_height="wrap_content",
 textSize="20",
 text="",
 -- id="tv_endTime",
 gravity="center";
 textColor="#27bb00",
 padding="30dp",
 layout_width="wrap_content"},
 {LinearLayout,
 layout_height="wrap_content",
 layout_width="match_parent",
 orientation="horizontal",
 -- layout_below="mainImageView1",
 id="mainLinearLayout2",
 gravity="center",
 layout_marginBottom="10dp",
 {TextView,
 layout_height="wrap_content",
 text="00:00",
 textColor="#ffffff",
 id="tv_startTime",
 layout_width="wrap_content"},
 {SeekBar,
 layout_height="wrap_content",
 style="progressBarStyleHorizontal",
 layout_width="wrap_content",
 id="mainProgressBar1",
 id="pb_time",
 layout_weight="1.0"
 },
 {TextView,
 layout_height="wrap_content",
 text="00:00",
 textColor="#ffffff",
 id="tv_endTime",
 layout_width="wrap_content"},
 },
 {LinearLayout,
 layout_height="wrap_content",
 layout_width="match_parent",
 orientation="horizontal",
 --layout_below="mainLinearLayout2",
 gravity="center",
 layout_marginBottom="10dp",
 {Button,
 layout_height="wrap_content",
 layout_weight="1";
 text="NEW",
 onClick=function ()
 解密小程序('openjm')
 end,
 layout_width="wrap_content"},
 {Button,
 layout_weight="1";
 layout_height="wrap_content",
 text="⏮",
 onClick="on_pre",
 layout_width="wrap_content"},
 {Button,
 layout_weight="1";
 layout_height="wrap_content",
 id="bn_pause",
 onClick="on_pause",
 text="▶",
 layout_width="wrap_content"},
 {Button,
 layout_weight="1";
 layout_height="wrap_content",
 text="⏭",
 onClick="on_next",
 layout_width="wrap_content"},
 {Button,
 layout_height="wrap_content",
 layout_weight="1";
 text="列表",
 onClick="on_playlist",
 layout_width="wrap_content"},
 },
 },
 }
};
--require "import"
import "android.app.*"
import "android.os.*"
import "android.widget.*"
import "android.view.View_*"
import "android.media.*"
import "android.view.*"
import "android.content.*"
import "java.io.*"
import "java.util.*"
import "android.content.Context"
import "android.provider.*"
--require "layout"
activity.setTitle("美美播放器")
activity.setTheme(android.R.style.Theme_Holo_Light)
local arr=nil
local pd--扫描进度条变量,定义在这容易操作
local mp=MediaPlayer()
local t=nil
local isPlay=false
local curPlay=nil --当前正在播放的mp3的路径
local listpath=tdata.."歌曲列表.txt"
local tf=File(listpath)
local dur--歌曲长度
local cur--播放当前位置
local min,sec=0,0--分和秒
local curIdx=0--当前播放的mp3在列表中的索引

--播放音乐，不异步可控
--@mp MediaPlayer对象
--@path 歌曲完整路径
function play(mp,path)
 mp.reset()
 mp.setDataSource(path)
 mp.prepare()
 mp.start()
end

--异步调用代码块，获取文件夹下的所有mp3文件。并存在arr中
local _getList= [[
require "import"
import "java.io.*"
local path,arr=...
local name,t

function _get(path)
 local f=File(path)
 local l=f.listFiles()
 
 for i=0,#l-1 do
 t=l[i]
 name= t.getName()
 if t.isFile() and string.find(string.lower(name),"%.mp3$") and t.length()>1024*1024*2 then --歌曲大于2m才添加
 arr.add(t)
 end
 if t.isFile() and string.find(string.lower(name),"%.m4a$") and t.length()>1024*1024*2 then --歌曲大于2m才添加
 arr.add(t)
 end
 if t.isDirectory() then
 _get(t.toString())
 end
 end --for
 end --_get
_get(path)--重要......
]]
--获取某文件夹下所有mp3文件。并存在arr中
function getList(path)
 arr=ArrayList()
 task( _getList,path,arr,getListFinish)
end
--回调函数，获取某文件夹下所有mp3文件完成时被调用
function getListFinish()
 writeFile(tdata.."歌曲列表.txt",arr)
 pd.cancel()
end
--写入文件
--@path 文件完整路径
--@list ArrayList
function writeFile(path,list)
 local fw=FileWriter(path)
 local bw=BufferedWriter(fw)
 for i=0,list.size()-1 do
 str=list.get(i).toString()
 bw.write(str,0,utf8.len(str))
 bw.newLine()
 end
 bw.flush()
 bw.close()
end
--读文件
--path 完整路径
--return ArrayList
function readFile(path)
 local al=ArrayList()
 local fr=FileReader(path)
 local br=BufferedReader(fr)
 local ch=0
 while(br.read()~=-1 )
 do
 al.add(br.readLine())
 end
 br.close()
 return al
end

--显示歌曲列表
--@path 列表文件路径
--@mediaplayer
function showList(path,mp)
 local al= readFile(path)
 arr=al
 local names={}
 local paths={}
 for i=0,al.size()-1 do
 table.insert(paths,al.get(i))
 table.insert(names,File(al.get(i)).getName())

 end
 local ad= AlertDialog.Builder(activity)
 ad.setTitle("歌曲列表")
 ad.setItems(String(names)
 ,DialogInterface.OnClickListener{
 onClick=function(dialog,which)
 curPlay=paths[which+1]
 curIdx=which
 play(mp,curPlay)
 local tt=string.gsub(names[which+1],".mp3$","")--偷懒一下
 tv_title.setText(tt)
 end
 })
 ad.setNegativeButton( "取消", nil)
 ad.setPositiveButton("更新列表",function(v)
 showEditDialog("输入路径以重新扫描")
 end)
 ad= ad.create()
 local window = ad.getWindow()
 local lp = window.getAttributes()
 --设置透明度
 lp.alpha = 0.8
 window.setAttributes(lp)
 ad.show()
end
--弹出进度条
--@text 进度条的文本
function showProcessBar(text)
 pd = ProgressDialog
 .show(activity, nil, text)
 pd.setCancelable(false)
end


--弹出文本框对话框
--@pa 进度条对象
function showEditDialog(msg)
 local edit=EditText(activity)
 edit.setText("/sdcard/music/")
 local dl =AlertDialog.Builder(activity)
 dl.setTitle(msg)
 dl.setView(edit)
 dl.setPositiveButton("确定",
 DialogInterface.OnClickListener{
 onClick=function(dialog,which)
 showProcessBar("扫描音乐中，请稍候……")
 getList(edit.getText().toString())
 end
 })
 dl.show()
end
--全局代码###################
if tf.exists()==false then--文件列表不存在
 showEditDialog("初次使用软件，设置扫描音乐的路径")
else
 arr= readFile(listpath)
end
--###################

--实时更新进度条和时间显示
function updateTime(m,s)
 if m<10 then m="0"..m end
 if s<10 then s="0"..s end
 tv_startTime.setText(m..":"..s)
 pb_time.setProgress(mp.getCurrentPosition())
end

--计时器代码
function _run(m,s)
 function run()

 s=s+1
 if(s==60) then
 m=m+1
 s=0
 end
 call("updateTime",m,s)
 end
end

--上一曲
function on_pre(v)
 if(curIdx>0) then
 curIdx=curIdx-1
 play(mp,arr.get(curIdx))
 local tt=string.gsub(File(arr.get(curIdx)).getName(),".mp3$","")--偷懒一下
 tv_title.setText(tt)
 local tt=string.gsub(File(arr.get(curIdx)).getName(),".m4a$","")--偷懒一下
 tv_title.setText(tt)
 end
end

--下一曲
function on_next(v)
 if(curIdx<arr.size()-1) then
 if curIdx==0 and not mp.isPlaying() then
 play(mp,arr.get(0))
 local tt=string.gsub(File(arr.get(curIdx)).getName(),".m4a$","")--偷懒一下
 tv_title.setText(tt)
 local tt=string.gsub(File(arr.get(0)).getName(),".mp3$","")--偷懒一下
 tv_title.setText(tt)
 else
 curIdx=curIdx+1
 play(mp,arr.get(curIdx))
 local tt=string.gsub(File(arr.get(curIdx)).getName(),".m4a$","")--偷懒一下
 tv_title.setText(tt)
 local tt=string.gsub(File(arr.get(curIdx)).getName(),".mp3$","")--偷懒一下
 tv_title.setText(tt)
 end
 end
end

--设置mediaPlayer播放结束时的回调函数
mp.setOnCompletionListener(MediaPlayer.OnCompletionListener{
 onCompletion=function(mper)
 -- print("歌曲播放结束")
 pb_time.setProgress(mp.getCurrentPosition())
 t.Enabled=false
 t.stop()
 t=nil
 on_next(v)
 end})

--时间转换函数
function formatTime(time)
 local min,sec=0,0
 sec=math.floor(time/1000)
 if(sec>60) then
 min=math.floor(sec/60)
 sec=math.floor(sec%60)
 end
 if min<10 then min="0"..min end
 if sec<10 then sec="0"..sec end
 return min..":"..sec
end
--时间设置
function setTime(time)
 local min,sec=0,0
 sec=math.floor(time/1000)
 if(sec>60) then
 min=math.floor(sec/60)
 sec=math.floor(sec%60)
 end

 return min,sec
end
--歌曲开始播放
mp.setOnPreparedListener(MediaPlayer.OnPreparedListener{
 onPrepared=function(mper)
 dur=mper.getDuration()--获取歌曲的时常
 pb_time.setMax(dur)
 local tt=formatTime(dur)
 tv_startTime.setText("00:00")
 tv_endTime.setText(tt)
 bn_pause.setText("⏯")
 min,sec=0,0
 if t~=nil then --计时器不为空就停止
 t.Enabled=false
 t.stop()
 t=nil
 end
 --歌曲开始播放又计时
 t=timer(_run,0,1000,min,sec)
 t.Enabled=true
 end})

--按下暂停时发生
function on_pause(v)
 if(mp.isPlaying()) then
 mp.pause()
 bn_pause.setText("▶")
 if(t~=nil) then
 t.Enabled=false
 end
 else
 if(t~=nil) then--如果为空那就是播放完了的情况
 mp.start()
 bn_pause.setText("⏯")
 t.Enabled=true
 end
 end
end

--按下"列表"按钮
function on_playlist(v)
 showList(listpath,mp)
end

function on_gx(v)
 showEditDialog("输入路径以重新扫描")
end

function on_out(v)
 if t~=nil then
 t.stop()
 end
 mp.stop()
 mp.release()--释放资源
 activity.finish()
end

activity.setTheme(android.R.style.Theme_DeviceDefault_Light_NoActionBar)
activity.setContentView(loadlayout(kksosoks))

--进度跳转
pb_time.setOnSeekBarChangeListener(
SeekBar.OnSeekBarChangeListener{
 onStopTrackingTouch=function(bar)
 if mp.isPlaying() then
 local cur=bar.getProgress()
 local tt=formatTime(cur)
 min,sec=setTime(cur)
 tv_startTime.setText(tt)
 mp.seekTo(cur)
 if t~=nil then --计时器不为空就停止
 t.Enabled=false
 t.stop()
 t=nil
 end
 --重新计时
 t=timer(_run,0,1000,min,sec)
 t.Enabled=true
 end
 end})

 ------分割线------以下到最后音量条点击事件-----
--导入AudioManager类
import "android.media.AudioManager"
--注意是改变媒体音量
--得到音频管理对象
mAudioManager = activity.getSystemService(Context.AUDIO_SERVICE);
--获取当前音乐音量
mVolume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

--设置为seekbar音量的最大阶数
seekbar.setMax(mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC));

--设置seekbar为当前音量进度
seekbar.setProgress(mVolume);
--绑定监听
seekbar.setOnSeekBarChangeListener{
 onProgressChanged=function(a,i)
 --拖动seekbar时改变音量
 mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, i, 0);--设置1显示音量调节窗口0为隐藏
 px=math.floor(i/mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)*100)
 if px<10 then
 seekText.Text=" 音量 : "..px.."% "
 elseif px==100 then
 seekText.Text=" 音量 : "..px.."%" 
 else
 seekText.Text=" 音量 : "..px.."% "
 end
 end}

-- 监听返回键
function onKeyDown(code, event)
 if code == KeyEvent.KEYCODE_BACK then -- 如果是返回键
 if mp.isPlaying() then
 mp.stop() -- 停止播放
 end
 end
 return false
end

