本文实例分享了一个简单的朋友圈程序,包含了朋友圈的列表实现,视频的录制、预览与上传,图片可选择拍照,供大家参考,具体内容如下
friendslistactivity 代码如下
public class friendslistactivity extends baseactivity implements onrefreshlistener<listview>, postlistener {
private interactionadapter madapter;
private pulltorefreshlistview mrefreshlistview;
private view mfooter;
private context mcontext;
private button btntopost;
protected int mpage = 0;
private boolean isrefreshing = false;
@override
protected void oncreate(bundle savedinstancestate) {
// todo auto-generated method stub
super.oncreate(savedinstancestate);
setcontentview(r.layout.friends_list);
mcontext=getapplicationcontext();
madapter = new interactionadapter(mcontext);
madapter.setlistener(this);
btntopost=(button) findviewbyid(r.id.btn_topost);
mrefreshlistview = (pulltorefreshlistview) findviewbyid(r.id.friends_list);
friendsapi.getfriendslist(mcontext, mcallback);
mrefreshlistview.setonrefreshlistener(this);
mfooter = layoutinflater.from(mcontext).inflate(r.layout.loading_footer, null);
// mrefreshlistview.getrefreshableview().addfooterview(mfooter);
mrefreshlistview.setadapter(madapter);
// mrefreshlistview.setonlastitemvisiblelistener(mlastlistener);
// mrefreshlistview.getrefreshableview().setdividerheight(40);
btntopost.setonclicklistener(new onclicklistener() {
@override
public void onclick(view v) {
myposts();
}
});
}
protected void myposts() {
new alertdialog.builder(this).setitems(new string[]{"图片","视频","文字"}, new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog, int which) {
intent intent=new intent();
switch (which) {
case 0:
intent.setclass(friendslistactivity.this, createpostactivity.class);
break;
case 1:
intent.setclass(friendslistactivity.this, recorderactivity.class);
break;
case 2:
intent.setclass(friendslistactivity.this, recorderactivity.class);
break;
default:
break;
}
startactivity(intent);
}
}).show();
}
/**
* 查看更多操作
*/
@override
public void show(interaction interaction) {
}
@override
public void delete(interaction interaction) {
// todo auto-generated method stub
}
@override
public void onrefresh(pulltorefreshbase<listview> refreshview) {
if (!isrefreshing) {
isrefreshing = true;
mpage = 0;
friendsapi.getfriendslist(mcontext, mcallback);
}
}
protected netcallback mcallback = new netcallback() {
public void friendslist(arraylist<interaction> friends) {
log.i("friends size>>>>",friends.size()+"-------------");
madapter.setinteractions(friends);
// mrefreshlistview.getloadinglayoutproxy().setlastupdatedlabel(null);
mrefreshlistview.onrefreshcomplete();
isrefreshing = false;
dismissloading();
};
public void start() {
showloading();
};
public void failed(string message) {
loadfailed();
};
};
@override
public void play(interaction interaction) {
intent mintent=new intent();
mintent.setclass(friendslistactivity.this, recorderplayactivity.class);
bundle data = new bundle();
data.putstring("path", interaction.videopath);
mintent.putextras(data);
startactivity(mintent);
}
}
布局文件 friends_list.xml
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/backgroud_color" >
<include
android:id="@+id/list_title"
android:layout_alignparenttop="true"
layout="@layout/list_title"/>
<com.yzl.xyb.friends.refresh.view.pulltorefreshlistview
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/friends_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/padding_left"
android:divider="@android:color/transparent"
android:layout_below="@+id/list_title"
app:ptroverscroll="false"
app:ptrheadertextcolor="#ff666666"
app:ptrheadertextappearance="@android:style/textappearance.small"
app:ptrshowindicator="false"/>
<include layout="@layout/loading"/>
</relativelayout>
适配器 interactionadapter 对朋友圈列表进行数据填充
public class interactionadapter extends baseadapter implements onclicklistener {
private arraylist<interaction> interactions;
private context mcontext;
private finalbitmap mfinal;
private bitmapdisplayconfig config;
private bitmapdisplayconfig imageconfig;
private postlistener listener;
public interactionadapter(context context) {
mcontext = context;
mfinal = finalbitmap.create(mcontext);
bitmap bitmap = bitmapfactory.decoderesource(mcontext.getresources(), r.drawable.user_avatar);
config = new bitmapdisplayconfig();
config.setanimationtype(bitmapdisplayconfig.animationtype.fadein);
config.setloadfailbitmap(bitmap);
config.setloadfailbitmap(bitmap);
bitmap = bitmapfactory.decoderesource(mcontext.getresources(), r.drawable.image_failed);
imageconfig = new bitmapdisplayconfig();
imageconfig.setanimationtype(bitmapdisplayconfig.animationtype.fadein);
imageconfig.setloadfailbitmap(bitmap);
imageconfig.setloadfailbitmap(bitmap);
}
public void setlistener(postlistener listener) {
this.listener = listener;
}
public void setinteractions(arraylist<interaction> interactions) {
this.interactions = interactions;
notifydatasetchanged();
}
@override
public int getcount() {
// todo auto-generated method stub
return interactions == null ? 0 : interactions.size();
}
@override
public object getitem(int position) {
// todo auto-generated method stub
return interactions.get(position);
}
@override
public long getitemid(int position) {
// todo auto-generated method stub
return position;
}
@override
public view getview(int position, view convertview, viewgroup parent) {
// todo auto-generated method stub
viewholder holder = null;
if (convertview == null) {
convertview = layoutinflater.from(mcontext).inflate(r.layout.friend_list_item, null);
holder = new viewholder();
holder.avatar = (circleimageview) convertview.findviewbyid(r.id.avatar);
holder.content = (textview) convertview.findviewbyid(r.id.content);
holder.title = (textview) convertview.findviewbyid(r.id.title);
holder.subtitle = (textview) convertview.findviewbyid(r.id.subtitle);
holder.image = convertview.findviewbyid(r.id.image_layout);
holder.image0 = (imageview) convertview.findviewbyid(r.id.image0);
holder.image1 = (imageview) convertview.findviewbyid(r.id.image1);
holder.image2 = (imageview) convertview.findviewbyid(r.id.image2);
holder.conments = (textview) convertview.findviewbyid(r.id.conment_count);
holder.praises = (textview) convertview.findviewbyid(r.id.parise_count);
holder.praised = (imageview) convertview.findviewbyid(r.id.praise_icon);
holder.more = (textview) convertview.findviewbyid(r.id.more);
holder.viewlayout=(linearlayout) convertview.findviewbyid(r.id.view_layout);
holder.surfaceview=(surfaceview) convertview.findviewbyid(r.id.surface_view_result);
holder.playbutton=(imagebutton) convertview.findviewbyid(r.id.btn_play_result);
holder.audiolayout=(framelayout) convertview.findviewbyid(r.id.audio_layout);
convertview.settag(holder);
} else {
holder = (viewholder) convertview.gettag();
}
interaction interaction = interactions.get(position);
if (textutils.isempty(interaction.avatar)) {
holder.avatar.setimagebitmap(config.getloadfailbitmap());
} else {
mfinal.display(holder.avatar, interaction.avatar, config);
}
holder.title.settext(interaction.name);
holder.subtitle.settext(interaction.subtitle);
holder.content.settext(interaction.content);
holder.conments.settext(string.valueof(interaction.commentcount));
holder.praises.settext(string.valueof(interaction.praisecount));
int images = interaction.images == null ? 0 : interaction.images.size();
if (images > 0) {
holder.image.setvisibility(view.visible);
holder.audiolayout.setvisibility(view.gone);
holder.image.setonclicklistener(this);
holder.image.settag(interaction);
if (images <= 1) {
mfinal.display(holder.image0, interaction.images.get(0), imageconfig);
holder.image1.setimagebitmap(null);
holder.image2.setimagebitmap(null);
} else if (images <= 2) {
mfinal.display(holder.image0, interaction.images.get(0), imageconfig);
mfinal.display(holder.image1, interaction.images.get(1), imageconfig);
holder.image2.setimagebitmap(null);
} else {
mfinal.display(holder.image0, interaction.images.get(0), imageconfig);
mfinal.display(holder.image1, interaction.images.get(1), imageconfig);
mfinal.display(holder.image2, interaction.images.get(2), imageconfig);
}
} else if(interaction.videopath!=null)
{
holder.image.setvisibility(view.gone);
holder.playbutton.setbackgroundresource(r.drawable.play1pressed);
holder.audiolayout.setvisibility(view.visible);
holder.playbutton.settag(interaction);
holder.playbutton.setonclicklistener(this);
holder.surfaceview.settag(interaction);
holder.surfaceview.setonclicklistener(this);
}else{
holder.viewlayout.setvisibility(view.gone);
}
holder.more.settag(interaction);
holder.more.setonclicklistener(this);
return convertview;
}
private class viewholder {
circleimageview avatar;
textview title;
textview subtitle;
textview content;
view image;
imageview image0;
imageview image1;
imageview image2;
textview conments;
textview praises;
imageview praised;
view delete;
textview more;
surfaceview surfaceview;
imagebutton playbutton;
framelayout audiolayout;
linearlayout viewlayout;
}
@override
public void onclick(view v) {
int id = v.getid();
if (id == r.id.btn_play_result) {
interaction interaction = (interaction) v.gettag();
}else if (id == r.id.surface_view_result) {
if (this.listener != null) {
this.listener.play((interaction) v.gettag());
}
}else if (id == r.id.more) {
if (this.listener != null) {
this.listener.show((interaction) v.gettag());
}
} else if (id == r.id.image_layout) {
intent intent = new intent(mcontext, mainactivity.class);
bundle data = new bundle();
interaction interaction = (interaction) v.gettag();
data.putstringarraylist("images", interaction.images);
intent.putextras(data);
mcontext.startactivity(intent);
}
}
public interface postlistener {
void show(interaction interaction);
void delete(interaction interaction);
void play(interaction interaction);
}
多图片选择实现代码
multipleactivity
package com.yzl.xyb.friends;
import java.io.file;
import java.io.filenamefilter;
import java.util.arraylist;
import java.util.arrays;
import java.util.hashset;
import java.util.list;
import android.app.activity;
import android.app.progressdialog;
import android.content.contentresolver;
import android.content.intent;
import android.database.cursor;
import android.net.uri;
import android.os.bundle;
import android.os.environment;
import android.os.handler;
import android.provider.mediastore;
import android.util.displaymetrics;
import android.util.log;
import android.view.layoutinflater;
import android.view.view;
import android.view.view.onclicklistener;
import android.view.viewgroup.layoutparams;
import android.view.windowmanager;
import android.widget.gridview;
import android.widget.popupwindow.ondismisslistener;
import android.widget.relativelayout;
import android.widget.textview;
import android.widget.toast;
import com.yzl.xyb.friends.adapter.myadapter;
import com.yzl.xyb.friends.adapter.myadapter.setcountlistener;
import com.yzl.xyb.friends.picture.listimagedirpopupwindow;
import com.yzl.xyb.friends.picture.listimagedirpopupwindow.onimagedirselected;
import com.yzl.xyb.friends.util.imagefloder;
/**
* 从相册选取图片
* 可以选择多张,最多可选9张
* 获取所有相册
* 确定:返回已选图片的路径
* @author hou
*
*/
public class multipleactivity extends activity implements onimagedirselected, setcountlistener{
private textview selectcount;
private textview selectpicture;
private textview mchoosedir;
private progressdialog mprogressdialog;
public static final int kitkat_less = 2;
/**
* 存储文件夹中的图片数量
*/
private int mpicssize;
/**
* 图片数量最多的文件夹
*/
private file mimgdir;
/**
* 所有的图片
*/
private list<string> mimgs;
private arraylist<string> pictures;
private gridview mgirdview;
private myadapter madapter;
/**
* 临时的辅助类,用于防止同一个文件夹的多次扫描
*/
private hashset<string> mdirpaths = new hashset<string>();
/**
* 扫描拿到所有的图片文件夹
*/
private list<imagefloder> mimagefloders = new arraylist<imagefloder>();
private relativelayout mbottomly;
int totalcount = 0;
private int mscreenheight;
private listimagedirpopupwindow mlistimagedirpopupwindow;
private handler mhandler = new handler()
{
public void handlemessage(android.os.message msg)
{
mprogressdialog.dismiss();
// 为view绑定数据
data2view();
// 初始化展示文件夹的popupwindw
initlistdirpopupwindw();
}
};
@override
protected void oncreate(bundle savedinstancestate)
{
super.oncreate(savedinstancestate);
setcontentview(r.layout.picture_selector);
getintent().getextras();
displaymetrics outmetrics = new displaymetrics();
getwindowmanager().getdefaultdisplay().getmetrics(outmetrics);
mscreenheight = outmetrics.heightpixels;
initview();
getimages();
initevent();
}
/**
* 初始化view
*/
private void initview()
{
mgirdview = (gridview) findviewbyid(r.id.id_gridview);
mchoosedir = (textview) findviewbyid(r.id.id_choose_dir);
selectcount = (textview) findviewbyid(r.id.tv_select_count);
// allphotoalum = (textview) findviewbyid(r.id.tv_photoalum);
selectpicture= (textview) findviewbyid(r.id.tv_sure);
mbottomly = (relativelayout) findviewbyid(r.id.id_bottom_ly);
}
private void initevent()
{
/**
* 为底部的布局设置点击事件,弹出popupwindow
*/
mbottomly.setonclicklistener(new onclicklistener()
{
@override
public void onclick(view v)
{
mlistimagedirpopupwindow
.setanimationstyle(r.style.anim_popup_dir);
mlistimagedirpopupwindow.showasdropdown(mbottomly, 0, 0);
// 设置背景颜色变暗
windowmanager.layoutparams lp = getwindow().getattributes();
lp.alpha = .3f;
getwindow().setattributes(lp);
}
});
selectpicture.setonclicklistener(new onclicklistener() {
@override
public void onclick(view v) {
pictures=madapter.getselectpath();
log.i("选中的图片1>>>>>>",pictures.size()+"----------");
intent intent=new intent();
// intent.setclass(multipleactivity.this, createpostactivity.class);
bundle bundle=new bundle();
bundle.putstringarraylist("pictures", pictures);
intent.putextras(bundle);
// startactivityforresult(intent, kitkat_less);
setresult(kitkat_less, intent);
finish();
}
});
}
/**
* 为view绑定数据
*/
private void data2view()
{
if (mimgdir == null)
{
toast.maketext(getapplicationcontext(), "擦,一张图片没扫描到",
toast.length_short).show();
return;
}
mimgs = arrays.aslist(mimgdir.list());
/**
* 可以看到文件夹的路径和图片的路径分开保存,极大的减少了内存的消耗;
*/
madapter = new myadapter(getapplicationcontext(), mimgs,
r.layout.grid_item, mimgdir.getabsolutepath());
madapter.setcountlistener(this);
mgirdview.setadapter(madapter);
// allpicturecount.settext("共"+totalcount + "张");
};
/**
* 初始化展示文件夹的popupwindw
*/
private void initlistdirpopupwindw()
{
mlistimagedirpopupwindow = new listimagedirpopupwindow(
layoutparams.match_parent, (int) (mscreenheight * 1),
mimagefloders, layoutinflater.from(getapplicationcontext())
.inflate(r.layout.list_dir, null));
mlistimagedirpopupwindow.setondismisslistener(new ondismisslistener()
{
@override
public void ondismiss()
{
// 设置背景颜色变暗
windowmanager.layoutparams lp = getwindow().getattributes();
lp.alpha = 1.0f;
getwindow().setattributes(lp);
}
});
// 设置选择文件夹的回调
mlistimagedirpopupwindow.setonimagedirselected(this);
}
/**
* 利用contentprovider扫描手机中的图片,此方法在运行在子线程中 完成图片的扫描,最终获得jpg最多的那个文件夹
*/
private void getimages()
{
if (!environment.getexternalstoragestate().equals(
environment.media_mounted))
{
toast.maketext(this, "暂无外部存储", toast.length_short).show();
return;
}
// 显示进度条
mprogressdialog = progressdialog.show(this, null, "正在加载...");
new thread(new runnable()
{
@override
public void run()
{
string firstimage = null;
uri mimageuri = mediastore.images.media.external_content_uri;
contentresolver mcontentresolver = multipleactivity.this
.getcontentresolver();
// 只查询jpeg和png的图片
cursor mcursor = mcontentresolver.query(mimageuri, null,
mediastore.images.media.mime_type + "=? or "
+ mediastore.images.media.mime_type + "=?",
new string[] { "image/jpeg", "image/png" },
mediastore.images.media.date_modified);
log.e("tag", mcursor.getcount() + "");
while (mcursor.movetonext())
{
// 获取图片的路径
string path = mcursor.getstring(mcursor
.getcolumnindex(mediastore.images.media.data));
log.e("tag", path);
// 拿到第一张图片的路径
if (firstimage == null)
firstimage = path;
// 获取该图片的父路径名
file parentfile = new file(path).getparentfile();
if (parentfile == null)
continue;
string dirpath = parentfile.getabsolutepath();
imagefloder imagefloder = null;
// 利用一个hashset防止多次扫描同一个文件夹(不加这个判断,图片多起来还是相当恐怖的~~)
if (mdirpaths.contains(dirpath))
{
continue;
} else
{
mdirpaths.add(dirpath);
// 初始化imagefloder
imagefloder = new imagefloder();
imagefloder.setdir(dirpath);
imagefloder.setfirstimagepath(path);
}
int picsize = parentfile.list(new filenamefilter()
{
@override
public boolean accept(file dir, string filename)
{
if (filename.endswith(".jpg")
|| filename.endswith(".png")
|| filename.endswith(".jpeg"))
return true;
return false;
}
}).length;
totalcount += picsize;
imagefloder.setcount(picsize);
mimagefloders.add(imagefloder);
if (picsize > mpicssize)
{
mpicssize = picsize;
mimgdir = parentfile;
}
}
mcursor.close();
// 扫描完成,辅助的hashset也就可以释放内存了
mdirpaths = null;
// 通知handler扫描图片完成
mhandler.sendemptymessage(0x110);
}
}).start();
}
@override
public void selected(imagefloder floder)
{
mimgdir = new file(floder.getdir());
mimgs = arrays.aslist(mimgdir.list(new filenamefilter()
{
@override
public boolean accept(file dir, string filename)
{
if (filename.endswith(".jpg") || filename.endswith(".png")
|| filename.endswith(".jpeg"))
return true;
return false;
}
}));
/**
* 可以看到文件夹的路径和图片的路径分开保存,极大的减少了内存的消耗;
*/
madapter = new myadapter(getapplicationcontext(), mimgs,
r.layout.grid_item, mimgdir.getabsolutepath());
madapter.setcountlistener(this);
mgirdview.setadapter(madapter);
// madapter.notifydatasetchanged();
// mimagecount.settext(floder.getcount() + "张");
mchoosedir.settext(floder.getname());
selectcount.settext("/9");
mlistimagedirpopupwindow.dismiss();
}
@override
public void docount(int a) {
selectcount.settext(a+"/9");
}
}
视频的录制与预览
package com.yzl.xyb.friends;
import android.annotation.suppresslint;
import android.app.activity;
import android.content.intent;
import android.os.bundle;
import android.os.handler;
import android.os.message;
import android.util.log;
import android.view.motionevent;
import android.view.view;
import android.view.view.ontouchlistener;
import android.widget.button;
import android.widget.toast;
import com.yzl.xyb.friends.view.movierecorderview;
import com.yzl.xyb.friends.view.movierecorderview.onrecordfinishlistener;
/**
* 录制视频
* @author hou
*
*/
public class recorderactivity extends activity {
private movierecorderview mrecorderview;
private button mshootbtn;
private boolean isfinish = true;
private string userid = "";
@override
protected void oncreate(bundle savedinstancestate) {
// todo auto-generated method stub
super.oncreate(savedinstancestate);
setcontentview(r.layout.record_activity);
// userid=getintent().getparcelableextra("userid");
mrecorderview = (movierecorderview) findviewbyid(r.id.movierecorderview);
mshootbtn = (button) findviewbyid(r.id.shoot_button);
mshootbtn.setontouchlistener(new ontouchlistener() {
@override
public boolean ontouch(view v, motionevent event) {
if (event.getaction() == motionevent.action_down) {
mrecorderview.record(new onrecordfinishlistener() {
@override
public void onrecordfinish() {
log.i("motionevent>>>","action_down");
handler.sendemptymessage(1);
}
});
} else if (event.getaction() == motionevent.action_up) {
log.i("motionevent>>>","action_up");
if (mrecorderview.gettimecount() > 1)
handler.sendemptymessage(1);
else {
if (mrecorderview.getmvecordfile() != null)
mrecorderview.getmvecordfile().delete();
mrecorderview.stop();
toast.maketext(recorderactivity.this, "时间太短,录制失败", toast.length_short).show();
}
}
return true;
}
});
}
@override
public void onresume() {
super.onresume();
isfinish = true;
}
@override
public void onsaveinstancestate(bundle outstate) {
super.onsaveinstancestate(outstate);
isfinish = false;
mrecorderview.stop();
}
@override
public void onpause() {
super.onpause();
}
@override
public void ondestroy() {
super.ondestroy();
}
@suppresslint("handlerleak")
private handler handler = new handler() {
@override
public void handlemessage(message msg) {
finishactivity();
log.i("isfinish>>>",isfinish+"");
}
};
private void finishactivity() {
if (isfinish) {
mrecorderview.stop();
intent intent = new intent(recorderactivity.this, topicactivity.class);
bundle mbundle = new bundle();
mbundle.putstring("path", mrecorderview.getmvecordfile().tostring());
mbundle.putstring("userid", userid);
intent.putextras(mbundle);
startactivity(intent);
}
}
public interface onshootcompletionlistener {
public void onshootsuccess(string path, int second);
public void onshootfailure();
}
}
视频的预览
package com.yzl.xyb.friends;
import android.app.activity;
import android.media.audiomanager;
import android.media.mediaplayer;
import android.os.bundle;
import android.view.surfaceholder;
import android.view.surfaceview;
import android.view.view;
import android.view.view.onclicklistener;
import android.widget.imagebutton;
import android.widget.imageview;
public class recorderplayactivity extends activity implements surfaceholder.callback, onclicklistener {
private imageview ivback;
private imagebutton btnplay;
private surfaceview surfaceview;
private surfaceholder surfaceholder;
private string path=null;
private mediaplayer player;
private boolean play=false;
@suppresswarnings("deprecation")
@override
protected void oncreate(bundle savedinstancestate) {
// todo auto-generated method stub
super.oncreate(savedinstancestate);
setcontentview(r.layout.recorder_play);
ivback=(imageview) findviewbyid(r.id.iv_back);
btnplay=(imagebutton) findviewbyid(r.id.ib_play);
surfaceview=(surfaceview) findviewbyid(r.id.play_view);
btnplay.setbackground(getresources().getdrawable(r.drawable.play1pressed));
path=this.getintent().getstringextra("path");
system.out.println("surface created>>>> path= "+path);
surfaceholder=surfaceview.getholder();
surfaceholder.addcallback(this);
surfaceholder.setfixedsize(320, 220);
surfaceholder.settype(surfaceholder.surface_type_push_buffers);
system.out.println("oncreate--------------");
ivback.setonclicklistener(this);
btnplay.setonclicklistener(this);
surfaceview.setonclicklistener(this);
}
@override
public void surfacecreated(surfaceholder holder) {
player=new mediaplayer();
player.setaudiostreamtype(audiomanager.stream_music);
player.setdisplay(surfaceholder);
try {
system.out.println("surface created>>>> path= "+path);
player.setdatasource(path);
player.prepare();
} catch (exception e) {
e.printstacktrace();
}
}
@override
public void surfacechanged(surfaceholder holder, int format, int width,
int height) {
// todo auto-generated method stub
}
@override
public void surfacedestroyed(surfaceholder holder) {
// todo auto-generated method stub
}
@override
public void onclick(view v) {
switch (v.getid()) {
case r.id.iv_back:
this.finish();
break;
case r.id.ib_play:
player.start();
btnplay.setvisibility(view.gone);
break;
case r.id.play_view:
player.pause();
/*if(play){
player.start();
}else {
player.pause();
}*/
btnplay.setvisibility(view.visible);
break;
default:
break;
}
}
@override
protected void ondestroy() {
// todo auto-generated method stub
super.ondestroy();
if(player.isplaying())
{
player.stop();
}
player.release();
}
}
拥有一个属于自己的朋友圈是不是很开新,可以和好朋友随时随地分享,是不是很开心!
以上就是本文的全部内容,希望对大家学习android软件编程有所帮助。