安卓AMR录音文件音量放大

public class AmrUtil {
	private static final int amrEncodeMode[] = { 4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200 }; // amr 编码方式
	private static final int AMR_FRAME_COUNT_PER_SECOND = 50;
	private static int mMode = 0;

	public static void change(String inPath, String outPath) {
		File inFile = new File(inPath);
		File outFile = new File(outPath);
		if (!inFile.exists()) {
			return;
		}
		try {
			outFile.deleteOnExit();
			outFile.createNewFile();

			FileInputStream in = new FileInputStream(inFile);
			FileOutputStream out = new FileOutputStream(outFile);

			byte[] amrhead = new byte[6];// amr head 6 bytes

			in.read(amrhead);
			out.write(amrhead);

			byte[] amrframehead = new byte[1];// amr frame head 1 bytes
			in.read(amrframehead);
			out.write(amrframehead);

			int frameSize = caclAMRFrameSize(amrframehead[0]);
			byte[] amrframecontent = new byte[frameSize - 1];// amr frame content frameSize - 1 bytes
			in.read(amrframecontent);
			out.write(amrframecontent);

			byte[] amrframe = new byte[frameSize];// amr frame frameSize bytes
			short[] pcmframe = new short[160];// pcm frame 160 shorts

			long state = AmrDecoder.init();
			AmrEncoder.init(0);

			while (in.read(amrframe) != -1) {
				AmrDecoder.decode(state, amrframe, pcmframe);
				int pcmval;
				for (int i = 0; i < pcmframe.length; i++) {
					// 音量调节
					pcmval = pcmframe[i] * 3;
					if (pcmval < 32767 && pcmval > -32768) {
						pcmframe[i] = (short) pcmval;
					} else if (pcmval > 32767) {
						pcmframe[i] = 32767;
					} else if (pcmval < -32768) { pcmframe[i] = -32768; } } AmrEncoder.encode(mMode, pcmframe, amrframe); out.write(amrframe); } in.close(); out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } } // 根据帧头计算当前帧大小 private static int caclAMRFrameSize(byte frameHeader) { int mode; int temp1 = 0; int temp2 = 0; int frameSize; temp1 = frameHeader; // 编码方式编号 = 帧头的3-6位 temp1 &= 0x78; // 0111-1000 temp1 >>= 3;
		
		mMode = temp1;
		mode = amrEncodeMode[temp1];

		// 计算amr音频数据帧大小
		// 原理: amr 一帧对应20ms,那么一秒有50帧的音频数据
		temp2 = myround((double) (((double) mode / (double) AMR_FRAME_COUNT_PER_SECOND) / (double) 8));

		frameSize = myround((double) temp2 + 0.5);
		return frameSize;
	}

	private static int myround(double x) {
		return ((int) (x + 0.5));
	}
}

参考:
1.AMR文件格式分析
2.opencore-amr-android

Android多渠道打包工具–MoeApkTool(通过assets目录内文件来区分渠道)

该工具参考自:RyApkTool特在此表示感谢~

1.原理

已签名APK文件==>ShakaApktool解压APK文件==>添加MOE_CHANNEL文件到assets目录

==>ShakaApktool重新打包APK文件==>jarsigner签名

MOE_CHANNEL文件里的内容就是渠道信息

2.用法

将APK文件放入工具包文件夹

CD到文件夹所在目录:java -jar MoeApkTool.jar keyFile keyName keyPasswd

3.编辑渠道信息

编辑工具包文件夹下的info文件夹里的channel.txt文件,一行一个渠道号

4.在程序里使用

点我看如何在程序里获取渠道号

5.下载地址

点我下载工具包

点我下载源码

【转】Java应用打包后运行需要注意编码问题

本文转载自:http://blog.csdn.net/chaijunkun/article/details/7624338

文章针对作者原文略有修改,以下是正文。

最近在做一个项目,项目总的来说就是和数据库打交道,取出数据来通过HTTP协议提交到一个接口上去。具体功能不多说了,只是讲这里面的一点——编码问题
项目当中,涉及到取所有数据的MD5值。
在Java项目中,个人喜欢将项目的默认编码改为UTF-8。使用的开发工具以Eclipse为主。然而,奇怪的问题出现了。当我在IDE中对项目进行调试的时候没有任何问题,但是打成了jar包后再通过

java -jar project.jar

运行的时候,每次提交数据,接口都会返回数据说我的签名不正确。换句话说就是我的最后一步,做MD5运算的时候出了问题。

为什么打了jar包就不行呢?几经波折,又是查看参数的hashCode,又是检查所有提交内容的十六进制数据,发现是文本编码出了问题。在Eclipse中是正确的,但是打出jar包后,启动命令行一直没设置字符串默认编码,因此java虚拟机就按照所在系统的默认编码运行了。我使用的是Windows环境,那么自然是GBK编码。

后来通过查阅资料,解决的办法就是加一个参数指定编码:
java -Dfile.encoding=utf-8 -jar project.jar
这样就可以了。工具正常运行了。

调用移动接口遇到的问题总结

方向一旦跑偏,造成的影响是非常大的。

1、请求地址问题

问题描述:移动接口的请求地址是IP地址,需要在header中设置host参数。测试过程中一直遇到400错误而不知道原因,于是决定在PC上面使用fidder进行抓包查看。抓到的包一直有问题,host地址始终是ip地址而不是设置好的域名。

问题原因:fidder抓手机包采用的是代理方式。抓包后对header中的host信息进行了改动。更深层次的原因是fidder采用了PC端的DNS解析。

问题解决:使用fidder抓包时,PC上面修改hosts文件,手机端请求地址改为域名方式。

2、Base64编码问题

问题描述:使用fidder抓包后发现,header信息中有一个参数不正确。移动方提示参数未设置。

问题原因:程序中使用了android.util.Base64进行Base64加密。该包进行加密的时候默认进行了自动换行操作。

问题解决:使用android.util.Base64包进行加密的时候,第二个参数需要改为Base64.NO_WRAP。

写一点关于安全的东西:)

一、双向消息加密

RSA,非对称加密算法。

DES,AES,对称加密算法。

用于服务端和客户端通讯。

客户端向服务端发送数据,采用RSA算法,使用公钥进行加密。服务端使用私钥进行解密。

服务端向客户端发送数据,采用DES或AES算法进行加密。客户端进行解密。

二、用户登录验证

谷歌验证 (Google Authenticator)

用于用户登录二次验证。

m3u8格式文件解析

public class VideoUtil {
/**
* 根据电影的m3u8_url解析出ts_url即xxx.ts形式url为元素的集合
* @param m3u8_url m3u8文件地址
* @return 返回ts_url集合
*/
public static ArrayList m3u8Parser(String m3u8_url){
try {
ArrayList list_ts = new ArrayList();
URL url = new URL(m3u8_url);
HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
InputStream in = urlConn.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line = “”;
while((line=reader.readLine())!=null){
if(line.startsWith(“#”)){
//这里是Metadata信息
}else if(line.length()>0){
//这里是一个指向的视频流路径 ,可能是绝对地址,也可能是相对地址
if(line.startsWith(“http”)){
//如果以http开头,一定是绝对地址了
list_ts.add(line);
}else{
//不以http开头,是相对地址,需要进行拼接。
String m3u8_pre = m3u8_url.substring(0, m3u8_url.lastIndexOf(“/”)+1);
list_ts.add(m3u8_pre+line);
}
}
}
in.close();
return list_ts;

} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}

Android自定义Toggleutton

1、设置自定义背景,设置on、off文案都为空

<ToggleButton
android:id=”@+id/lockBtn”
android:background=”@drawable/lock_me”
android:textOn=””
android:textOff=””/>

2、自定义背景文件

<selector xmlns:android=”http://schemas.android.com/apk/res/android”>
<item android:state_checked=”true”
android:drawable=”@drawable/lock_me_on” /> <!– pressed –>
<item android:drawable=”@drawable/lock_me_off” /> <!– default/unchecked –>
</selector>

3、按钮的监听

mLockBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(mLockBtn.isChecked()){
//锁定
mLockFlag = true;
mSeekBar.setEnabled(false);
mTopView.setVisibility(View.GONE);
mBottomView.setVisibility(View.GONE);
}else{
//取消锁定
mLockFlag = false;
mSeekBar.setEnabled(true);
mTopView.setVisibility(View.VISIBLE);
mBottomView.setVisibility(View.VISIBLE);
}
}
});

【转】修改Android签名证书keystore的密码、别名alias以及别名密码

原文地址:http://blog.k-res.net/archives/1671.html

之前在测试Eclipse ADT的Custom debug keystore自定义调试证书的时候,发过一篇关于调试证书规格的博文:Eclipse ADT的Custom debug keystore所需证书规格,提到过自定义调试证书的密码和alias命名以及alias密码都是有规矩的。其实Android应用开发接入各种SDK时会发现,有很多SDK是需要靠package name和keystore的指纹hash来识别的(百度地图SDK、Facebook SDK等等…),这样如果使用默认自动生成的debug keystore的话就会给开发调试工作带来一些麻烦。这时可以通过修改正式的release keystore,生成一份“遵守规矩”的临时自定义调试证书给开发时用,就方便多了,具体方法如下: 继续阅读【转】修改Android签名证书keystore的密码、别名alias以及别名密码

【转】Eclipse ADT的Custom debug keystore所需证书规格

原文地址:http://blog.k-res.net/archives/1229.html

最近开始研究Google Play的In-app Billing IAB内置计费API,发现一个比较烦人的问题就是测试时应用必须经过正式签名,而默认Eclipse ADT调试运行使用的是临时生成的Debug专用证书,默认为C:\Users\XXX\.android\debug.keystore

于是每次调试内置计费必须使用ADT的Export Signed Application Package打带正式签名的包,比较麻烦。后来发现ADT允许自定义调试用证书,在Window->Preferences->Android->Build->Custom debug keystore这里,试了一下选择正式证书后提示:”Keystore was tampered with, or password was incorrect”,如下图所示:

QQ20130308142554
其实这个界面并没有提供输入Keystore密码,选择别名之类的地方,所以就感到非常奇怪了,查了一下官方文档发现,即使是自定义的调试证书,也需要保证和默认证书一样的密码,别名alias和别名密码。

文档中提到的默认证书信息如下:

Keystore name: “debug.keystore”
Keystore password: “android
Key alias: “androiddebugkey”
Key password: “android”
CN: “CN=Android Debug,O=Android,C=US”

遵循这个规则就可以用自定义调试证书了。不过仔细想想感觉这功能这样很是鸡肋,希望以后版本的ADT会改进吧。