今天我来介绍在android手机开发中我们利用Service播放音乐实例,这里需要有一个xml文档列表来存储音乐的地址,然后通过下面的程序读取音乐文件进行播放了。
Android Service 的使用:
我们可以创建一个Android程序,在src目录下创建一个Activity,一个继承自Service类的服务类;同时在资源文件夹res目录下创建一个raw的文件夹存放音频文件,如把music.mp3音乐文件放在该目录下。该程序的主界面如下:
xml布局
代码如下 |
复制代码 |
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Welcome to Andy's blog!"
android:textSize="16sp"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="音乐播放服务"/>
<Button
android:id="@+id/startMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启音乐播放服务"/>
<Button
android:id="@+id/stopMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止音乐播放服务"/>
<Button
android:id="@+id/bindMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="绑定音乐播放服务"/>
<Button
android:id="@+id/unbindMusic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解除 ——绑定音乐播放服务"/>
</LinearLayout>
|
java代码
代码如下 |
复制代码 |
MusicService.java
package com.zeph.android.service;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
public class MusicService extends Service {
private MediaPlayer mMediaPlayer;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mMediaPlayer = MediaPlayer.create(this, R.raw.music01);
}
@Override
public void onDestroy() {
super.onDestroy();
mMediaPlayer.stop();
mMediaPlayer.release();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
int operate = intent.getIntExtra("operate", 3);
switch (operate) {
case 0:
if (!mMediaPlayer.isPlaying()) {
mMediaPlayer.start();
}
break;
case 1:
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.pause();
}
break;
case 2:
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
mMediaPlayer = MediaPlayer.create(this, R.raw.music01);
}
break;
default:
break;
}
}
}
ServiceTestActivity.java
package com.zeph.android.service;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ServiceTestActivity extends Activity {
private Button playButton;
private Button pauseButton;
private Button stopButton;
private Button stopService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
playButton = (Button) findViewById(R.id.playButton);
pauseButton = (Button) findViewById(R.id.pauseButton);
stopButton = (Button) findViewById(R.id.stopButton);
stopService = (Button) findViewById(R.id.stopService);
playButton.setOnClickListener(new ButtonOnClickListener());
pauseButton.setOnClickListener(new ButtonOnClickListener());
stopButton.setOnClickListener(new ButtonOnClickListener());
stopService.setOnClickListener(new ButtonOnClickListener());
}
public class ButtonOnClickListener implements OnClickListener {
@Override
public void onClick(View view) {
Intent intent = new Intent();
intent.setClass(getApplicationContext(), MusicService.class);
if (view == playButton) {
intent.putExtra("operate", 0);
startService(intent);
} else if (view == pauseButton) {
intent.putExtra("operate", 1);
startService(intent);
} else if (view == stopButton) {
intent.putExtra("operate", 2);
startService(intent);
} else if (view == stopService) {
stopService(intent);
}
}
}
}
|
服务还需要在AndroidManifest.xml注册后才能使用:
代码如下 |
复制代码 |
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pocketdigi.service"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:enabled="true" android:name=".Music" />
</application>
</manifest>
|
今天文章来给各位安卓开者提供两个在应用中不错的实例,在安卓一个实例手动更新模块和自动更新模块程序代码,希望此代码对各位有帮助。
这里介绍了实现原理,为了使用方便,简单封装了一个类Updater。用法很简单。好吧,为了支持多语言,其实还是有些繁琐。
用法:
strings.xml 中用到的字符定义
其他语言的自己添加,下面的实例程序中,中英文都有
代码如下 |
复制代码 |
<string name="update">check for update</string>
<string name="help">Help?</string>
<string name="help_content">I am helper,muhaha~~~</string>
<string name="found_newversion">Found a new version</string>
<string name="need_update">need update?</string>
<string name="alertdialog_title">Software Update</string>
<string name="alertdialog_update_button">Update</string>
<string name="alertdialog_cancel_button">Not now</string>
<string name="progressdialog_title">Downloading update</string>
<string name="progressdialog_message">Please wait a moment</string>
|
在AndroidManifest.xml添加更新需要用到的权限
代码如下 |
复制代码 |
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
|
检查更新,如发现有新版本会弹出提示
代码如下 |
复制代码 |
private boolean checkUpdate() {
Updater updater = new Updater("http://127.0.0.1/", this);
if (updater.needUpdate())//found update
updater.showNewVersionUpdate();
else {
}
return true;
} |
自动更新
之前帮别人定制的一个android应用需要加个自动更新的功能。在 Market 里的应用是无需操心此事的,但像我这种定制的程序就需要自己实现。
原理相当简单,检查更新的时候,通过指定的URL获取服务器端版本信息。比较版本,如果更新,访问服务器端返回的apk的URL地址,下载,安装。各种 Makert 也是通过类似的机制实现的。原理搞清楚了,代码就相当简单了。
获取apk的VesionName,即AndroidManifest.xml中定义的android:versionName
代码如下 |
复制代码 |
public String getVesionName(Context context) {
String versionName = null;
try {
versionName = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionName;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return versionName;
}
|
更新以及安装程序需要的权限,在AndroidManifest.xml中添加
代码如下 |
复制代码 |
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission>
|
获取apk的versionCode,即AndroidManifest.xml中定义的android:versionCode
代码如下 |
复制代码 |
public int getVersionCode(Context context) {
int versionCode = 0;
try {
versionCode = context.getPackageManager().getPackageInfo("net.vpntunnel", 0).versionCode;
} catch (NameNotFoundException e) {
Log.e(TAG, e.getMessage());
}
return versionCode;
}
|
服务器端version.JSON,包含apk路径以及版本信息
代码如下 |
复制代码 |
{
"ApkName":"NAME",
"ApkFullName":"NAME_1.0.5.apk",
"VersionName":"1.0.5",
"VersionCode":3
}
|
获取远程服务器的版本信息
代码如下 |
复制代码 |
private void getRemoteJSON(string host) throws ClientProtocolException, IOException, JSONException {
String url = String.format("http://%s/%s", host, VER_JSON);
StringBuilder sb = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpParams httpParams = client.getParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpResponse response = client.execute(new HttpGet(url));
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "n");
}
reader.close();
}
JSONObject object = (JSONObject) new JSONTokener(sb.toString()).nextValue();
this.apkFullName = object.getString("ApkFullName");
this.versionName = object.getString("VersionName");
this.versionCode = Integer.valueOf(object.getInt("VersionCode"));
}
|
发现更新的提醒窗口,通过AlertDialog实现
代码如下 |
复制代码 |
private void shoVersionUpdate(String newVersion, final String updateURL) {
String message = String.format("%s: %s, %s", mContext.getString(R.string.found_newversion), newVersion, mContext.getString(R.string.need_update));
AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle(mContext.getString(R.string.alertdialog_title)).setMessage(message)
// update
.setPositiveButton(mContext.getString(R.string.alertdialog_update_button), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
pBar = new ProgressDialog(mContext);
pBar.setTitle(mContext.getString(R.string.progressdialog_title));
pBar.setMessage(mContext.getString(R.string.progressdialog_message));
pBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
dialog.dismiss();
downFile(updateURL);
}
// cancel
}).setNegativeButton(mContext.getString(R.string.alertdialog_cancel_button), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
dialog.dismiss();
}
}).create();
dialog.show();
}
|
下载新版的apk文件,存放地址可以放到SD卡中。通过Environment.getExternalStorageDirectory()获取SD卡中的路径
代码如下 |
复制代码 |
private void downFile(final String url) {
pBar.show();
new Thread() {
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpResponse response;
try {
response = client.execute(get);
HttpEntity entity = response.getEntity();
long length = entity.getContentLength();
InputStream is = entity.getContent();
FileOutputStream fileOutputStream = null;
if (is != null) {
File f = new File(UPDATE_DIR);
if (!f.exists()) {
f.mkdirs();
}
fileOutputStream = new FileOutputStream(new File(UPDATE_DIR, updateFileName));
byte[] buf = new byte[1024];
int ch = -1;
int count = 0;
while ((ch = is.read(buf)) != -1) {
fileOutputStream.write(buf, 0, ch);
count += ch;
Log.d(TAG, String.valueOf(count));
if (length > 0) {
}
}
}
fileOutputStream.flush();
if (fileOutputStream != null) {
fileOutputStream.close();
}
handler.post(new Runnable() {
public void run() {
pBar.cancel();
installUpdate();
}
});
} catch (Exception e) {
pBar.cancel();
Log.e(TAG, e.getMessage());
}
}
}.start();
}
|
安装更新
代码如下 |
复制代码 |
private void installUpdate() {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(UPDATE_DIR, updateFileName)), "application/vnd.android.package-archive");
mContext.startActivity(intent);
}
|
至此更新需要函数就完成了,根据自己的业务逻辑组合一下,更新功能就搞定了。也可以稍微封装下,写成一个通用类,下次就可以直接用了。
有一个注册界面,有四个可填项:
用户名,密码,确认密码,手机号码
我就是想知道,当我填完了四项内容后,点击提交按钮,我所填的内容能保存在应用中,并在再次调到登录界面时能用刚注册的信息成功登录,这是可以实现的吧?
1:代码实现切换操作
2:配置中声明另外一个acitivity
我们先看第一步,这里是触屏处理中的一段代码:
代码如下 |
复制代码 |
public boolean onTouchEvent(MotionEvent event) {
float pointx = event.getX();
float pointy = event.getY();
if (pointx > bp_x + 14 && pointx < bp_x + 14 + 117) {
if (pointy > bp_y + 43 && pointy < bp_y + 43 + 15) {
// 帐号
Intent i = new Intent();// 得到一个意图的实例
i.putExtra("count", 1);// 写出数据
i.putExtra("himi", str_zh);
i.setClass(MainActivity.instance, Register.class);// 设置当前activity以及将要操作的类
MainActivity.instance.startActivity(i);// 用当前activity来启动另外一个activity
}
}
}
|
显示定义一个intent对象,Intent这个类的机制是协助交互的,详细的说明这里不多讲。
Intent中的putExtra()函数是起到两个activity之间交互交互的作用,这个方法类似 hashtable 或者hashmap中的put,第一个参数是key(索引) ,后一个参数volue(值),根据key我们可以得到对应的volue了。那么后面我也附上接受的处理。
Intent 中的setClass()函数也是传入两个参数,第一个是传入当前实例的activity对象,后面一个参数指需要打开的activity这个类!然后我们就可以利用当前activity对象来启动另外一个activity了。然后我们看下在另外一个activity是如何创建并且怎么接受数据的。
代码如下 |
复制代码 |
package com.himi;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
/** * @author Himi **/
public class Register extends Activity {
private Button button_ok;
private EditText et;
private TextView tv;
private LinearLayout ly;
private Register rs;
private byte count;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rs = this;
ly = new LinearLayout(this);
button_ok = new Button(this);
button_ok.setWidth(100);
button_ok.setText("确定");
button_ok.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (count == 1) {
MySurfaceView.str_zh = et.getText().toString();
}
else if (count == 2) {
MySurfaceView.str_pass = et.getText().toString();
}
rs.finish();
}
});
Intent intent = this.getIntent();
count = (byte) intent.getIntExtra("count", 0);
String temp_str = "";
String temp_str2 = "";
et = new EditText(this);
tv = new TextView(this);
if (count != 3) {
temp_str = intent.getStringExtra("himi");
if (count == 1) {
rs.setTitle("请输入帐号!");
}
else {
rs.setTitle("请输入密码!");
}
ly.addView(tv);
ly.addView(et);
ly.addView(button_ok);
if (temp_str != null) {
et.setText(temp_str);
}
}
else {
temp_str = intent.getStringExtra("himi_zh");
temp_str2 = intent.getStringExtra("himi_pass");
rs.setTitle("您输入的信息:");
tv.setText("帐号:" + temp_str + "n" + "密码" + temp_str2);
ly.addView(tv);
ly.addView(button_ok);
if (temp_str != null) {
et.setText(temp_str);
}
}
setContentView(ly);
}
}
|
以上代码可以看出,新建一个activity其实只需要继承Activity以及重写onCreate()方法即可。当然创建的还需要一步很重要的步骤,我会在第二步中会详细说明,这里我们看下是如何接受之前的activity传来数据的。
代码如下 |
复制代码 |
Intent intent = this.getIntent();
count = (byte) intent.getIntExtra("count", 0);
|
接受也是很简明易懂,创建一个Intent 意图对象,调用来去getIntExtra函数得到之前传来的数据,根据key。当然还有getStringExtra()等等函数都是类似,只是根据你传入的数据不同选择不同函数罢了。同学们应该注意的是getIntExtra中第二个参数是什么意思,其实就是一个对于找不到key相匹配的时候会默认return 0;
那么下面介绍第二步:在配置中声明
当创建一个activity的时候我们必须在AndroidMainFeset.xml中去声明我们创建的这个类是个Activity。
本文章来给大家介绍关于android.os.BinderProxy cannot be cast to com解决办法,希望此文章对各位有帮助呀。
Android在绑定服务的时候出现java.lang.ClassCastException:android.os.BinderProxy cannot be cast to com.
修改manifest文件里边相关服务去掉android:process=":remote"即可。
本文章来给大家介绍在安卓手机开发中的常用文件操作代码,这里一个不错的文件操作类,希望对大家有所帮助哦。
代码如下 |
复制代码 |
package cn.youxigu.files;
import cn.youxigu.service.*;
import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.view.*;
public class MainActivity extends Activity {
EditText filename;
EditText content;
Button buttonsave;
Button buttonopen;
Button buttonsaveSdCard;
Button buttonopenSdCard;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
filename = (EditText)this.findViewById(R.id.filename);
content = (EditText)this.findViewById(R.id.content);
//获取本地保存按钮
buttonsave = (Button)this.findViewById(R.id.buttonsave);
//获取本地打开按钮
buttonopen = (Button)this.findViewById(R.id.buttonsaveopen);
//获取SD卡保存按钮
buttonsaveSdCard = (Button)this.findViewById(R.id.buttonsavesdcard);
//获取SD卡打开按钮
buttonopenSdCard = (Button)this.findViewById(R.id.buttonsaveopensdcard);
buttonsave.setOnClickListener(new SaveFileClick());
buttonopen.setOnClickListener(new OpenFileClick());
buttonsaveSdCard.setOnClickListener(new SaveSdCardFileClick());
buttonopenSdCard.setOnClickListener(new OpenSdCardFileClick());
}
/**
* 保存到本地的存储
* @author xiaolu
*
*/
private final class SaveFileClick implements View.OnClickListener{
@Override
public void onClick(View v) {
String files = filename.getText().toString();
String contents = content.getText().toString();
FileService file = new FileService(getApplicationContext());
try{
file.save(files, contents);
Toast.makeText(getApplicationContext(), "保存成功", 1).show();
} catch (Exception e){
Toast.makeText(getApplicationContext(), "保存失败", 1).show();
e.printStackTrace();
}
}
}
/**
* 打开本地的存储
* @author xiaolu
*
*/
private final class OpenFileClick implements View.OnClickListener{
@Override
public void onClick(View v) {
String filenames = filename.getText().toString();
FileService file = new FileService(getApplicationContext());
try{
String contents = file.read(filenames);
//填充到文本框
content.setText(contents);
Toast.makeText(getApplicationContext(), "打开成功", 1).show();
} catch (Exception e){
Toast.makeText(getApplicationContext(), "打开失败", 1).show();
e.printStackTrace();
}
}
}
/**
* 保存到SD卡的存储
* @author xiaolu
*
*/
private final class SaveSdCardFileClick implements View.OnClickListener{
@Override
public void onClick(View v) {
String files = filename.getText().toString();
String contents = content.getText().toString();
FileService file = new FileService(getApplicationContext());
try{
file.saveSdCard(files, contents);
Toast.makeText(getApplicationContext(), "保存到SD卡成功", 1).show();
} catch (Exception e){
Toast.makeText(getApplicationContext(), "保存到SD卡失败", 1).show();
e.printStackTrace();
}
}
}
/**
* 打开SD卡的存储
* @author xiaolu
*
*/
private final class OpenSdCardFileClick implements View.OnClickListener{
@Override
public void onClick(View v) {
String filenames = filename.getText().toString();
FileService file = new FileService(getApplicationContext());
try{
String contents = file.readSdCard(filenames);
//填充到文本框
content.setText(contents);
Toast.makeText(getApplicationContext(), "打开SdCard成功", 1).show();
} catch (Exception e){
Toast.makeText(getApplicationContext(), "打开SdCard失败", 1).show();
e.printStackTrace();
}
}
}
}
|
FileService文件代码:
代码如下 |
复制代码 |
package cn.youxigu.service;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.content.Context;
import android.os.Environment;
public class FileService {
//获取上下文
private Context context;
public FileService(Context context){
this.context = context;
}
/**
* 读取本地存储文件内容
* @param filename 文件名
* @return 文件内容
* @throws Exception
*/
public String read(String filename) throws Exception{
FileInputStream InputStream = context.openFileInput(filename);
//申请写入内存
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = InputStream.read(buffer)) != -1){
outStream.write(buffer);
}
byte[] data = outStream.toByteArray();
return new String(data);
}
/**
* 保存到本地存储
* @param filename 文件名
* @param content 文件内容
* @throws Exception
*/
public void save(String filename, String content) throws Exception{
FileOutputStream outStream = context.openFileOutput(filename, Context.MODE_PRIVATE);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 保存到SdCard存储
* @param filename 文件名
* @param content 文件内容
* @throws Exception
*/
public void saveSdCard(String filename, String content) throws Exception{
//获取SD卡路径
File sdCardDir = Environment.getExternalStorageDirectory();
File saveFile = new File(sdCardDir, filename);
FileOutputStream outStream = new FileOutputStream(saveFile);
outStream.write(content.getBytes());
outStream.close();
}
/**
* 读取SdCard存储文件内容
* @param filename 文件名
* @return 文件内容
* @throws Exception
*/
public String readSdCard(String filename) throws Exception{
//获取SD卡路径
File sdCardDir = Environment.getExternalStorageDirectory();
File openFile = new File(sdCardDir, filename);
//用输入流对象进行读取数据
FileInputStream InputStream = new FileInputStream(openFile);
//申请写入内存
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
while((len = InputStream.read(buffer)) != -1){
outStream.write(buffer);
}
byte[] data = outStream.toByteArray();
return new String(data);
}
}
|
main.xml 文件代码:
代码如下 |
复制代码 |
<?xml version=“1.0″ encoding=“utf-8″?>
<LinearLayout xmlns:android=“http://schemas.android.com/apk/res/android”
android:layout_width=“fill_parent”
android:layout_height=“fill_parent”
android:orientation=“vertical” >
<TextView
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:text=“@string/filenametext” />
<EditText
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:id=“@+id/filename”/>
<EditText
android:layout_width=“fill_parent”
android:layout_height=“wrap_content”
android:minLines=“3″
android:id=“@+id/content”/>
<Button
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@string/buttonsave”
android:id=“@+id/buttonsave”
/>
<Button
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@string/buttonopen”
android:id=“@+id/buttonsaveopen”
/>
<Button
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@string/buttonsavesdcard”
android:id=“@+id/buttonsavesdcard”
/>
<Button
android:layout_width=“wrap_content”
android:layout_height=“wrap_content”
android:text=“@string/buttonopensdcard”
android:id=“@+id/buttonsaveopensdcard”
/>
</LinearLayout> |