公告:九九网站目录为广大站长提供免费收录网站服务,会员可在线完成投稿无需添加友情链接。只收录内容正规合法的网站;快审网站软文10元

点击这里在线咨询客服
新站提交
  • 网站:8462
  • 待审:16
  • 小程序:9
  • 文章:3610
  • 会员:21113

 

android 设置环境变量:

ANDROID_SDK_HOME D:\android

如果不指定该变量,那么模拟器文件将存放在默认c:\documents and settings\user

(当计算机用户名为中文时,可以通过该变量解决模拟器无法创建的问题)

android-sdk\platforms文件里面放的是 所有android版本

android常用命令(android-sdk\tools里面的命令):

列出所有创建的模拟器

android list avds

列出所有SDK可用版本

android list targets

创建模拟器命令:

android create avd -n(--name) <名字> -t(--target)

adb常用命令(android-sdk\platform-tools里面的命令):

列出所有连接手机或模拟器设备

adb devices

进入设备根目录,取得对设备的控制权(进入后可使用LINUX命令)

adb shell (ls:显示目录列表)

安装apk

单设备命令:adb install xxx.apk

多设备命令:adb install -s emulator-5554 xxx.ap (指定安装到哪个手机)

如果已经安装,提示不能再安装时,可以通过如下命令:

adb install -r xxx.apk

软件卸载

adb uninstall <包名>

向sdcard中放入文件

adb push

从手机空间或sdcard取出文件

adb pull

例:adb push the9.png /sdcard/

启动一个模拟器

emulator -avd

创建sdcard

mksdcard 256M e:\program\android\sdcard.img (创建一个236M的sdcard)

android,Activity跳转界面:

Intent itt=new Intent(FirstActivity.this,SecondActivity.class);

intent.putExtra("cid", 2); //往intent里面放数据,如果要传对象,就要把对象Serializable,后面得到对象用getSerializableExtra

//Intent itt=new Intent();

//itt.setClassName(FirstActivity.this, "com.kt1127.SecondActivity");

startActivity(itt);

android,Activity弹出类似对话框(有返回值的):

Intent intent=new Intent(FirstActivity.this,SecondActivity.class);

startActivityForResult(intent, REQUESTID);

//重写onActivityResult方法 得到对话框返回的值

每一个Activity都必须在AndroidManifest.xml中使用标签进行配置

让一个Activity对话框风格:

在AndroidManifest.xml文件中

在Activity加入这样一句话:

android:theme="@android:style/Theme.Dialog"

在values的string.xml里定义一个字符串数组:

并在Activity里面调用该数组:

Resources res=getResources();

String[] strs=res.getStringArray(R.array.strArr);//这里用的是R.array.了, 而不是R.string.

在AndroidManifest.xml设置权限:

实现打电话(下面的方法需要在AndroidManifest.xml添加权限):

Intent intent=new Intent();

intent.setAction(Intent.ACTION_CALL); //设置行为--打电话

Uri uri=Uri.parse("tel:"+u.getPhone()); //uri 必须为 tel:********

intent.setData(uri);

startActivity(intent);

在TextView中设置android:id="@android:id/empty", 表示界面什么也没有时显示该TextView,(这是在使用 系统的ListView 的前提下的)

弹出一个小文本信息:

Toast.makeText(TestLayoutActivity.this, str, 1000).show(); //显示1秒 ,str--要显示的字符串

android:layout_gravity="center_horizontal" //表示 自己在布局 居中

android:gravity="center" //表示里面的内容 居中

发送短信的两种方式:

1. 我们程序直接发送(需要在AndroidManifest.xml添加权限):

SmsManager smsManager=SmsManager.getDefault(); //这里导包,要的是 android.telephony.SmsManager的,另外一个过时了

String tel=telEt.getText().toString();

String content=smsEt.getText().toString();

ArrayList contents=smsManager.divideMessage(content);

for(String s:contents){

smsManager.sendTextMessage(tel, null, s, null, null);

Toast.makeText(SmsActivity.this, "发送成功!", 1000).show();

}

2. 利用第三方(也就是系统软件),会跳转界面再点击发送(不需要添加权限):

Intent intent=new Intent();

intent.setAction(Intent.ACTION_SENDTO);

intent.setData(Uri.parse("smsto:"+tel));

intent.putExtra("sms_body", content);

startActivity(intent);

布局中FrameLayout是从左上角开始显示,不能指定位置,但是允许多个控件显示(是直接覆盖);

AbsoluteLayout 现在一般不用了;

RelativeLayout :

android:layout_toRightOf="@id/tel_label" //表示在tel_label的右边,用 id 来做相对布局

android:layout_below="@id/content" //表示在content的下面

删除ListView的item:

users.remove(position); //移除adapter里面的数据

adapter.notifyDataSetChanged();

ListView:

ListView成为勾选列表:

/*

**R.layout.checkitem这个布局里面用CheckedTextView,

**并且要有属性android:checkMark="?android:attr/listChoiceIndicatorSingle" //设置勾选中了, 是圆点

**

*/

adapter = new ArrayAdapter(this, R.layout.checkitem, strs);

lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

ListView的优化:

1. 如果自定义适配器,那么在getView方法中要考虑方法传进来的参数contentView是否为null,如果为null就创建contentView并返回,如果不为null则直接使用。在这个方法中尽可能少创建view。

2. 给contentView设置tag(setTag()),传入一个viewHolder对象,用于缓存要显示的数据,可以达到图像数据异步加载的效果。

//实例:

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = View.inflate(MainActivity.this, R.layout.item, null);
        holder = new ViewHolder();
        holder.imgV = (ImageView) convertView.findViewById(R.id.img);
        holder.textV = (TextView) convertView.findViewById(R.id.text);
        convertView.setTag(holder);
    }else{
        holder = (ViewHolder) convertView.getTag();
    }
    holder.imgV.setImageResource((Integer) data.get(position).get("img"));
    holder.textV.setText((String) data.get(position).get("text"));
    return convertView;
}
class ViewHolder {
    ImageView imgV;
    TextView textV;
}

3. 如果listview需要显示的item很多,就要考虑分页加载。比如一共要显示100条或者更多的时候,我们可以考虑先加载20条,等用户拉到列表底部的时候再去加载接下来的20条。

SimpleAdapter:

/*
	**this	---	context
	**data	---	List里面必须放 Map
	**R.layout.simple	---	布局,就是设置item的布局
	**new String[]{"name","tel"}	---	String[],对应Map里面的Keys
	**new int[]{R.id.name,R.id.tel}	---	int[],对应上面布局的View的id ,
	*/
	SimpleAdapter spa=new SimpleAdapter(this,data,R.layout.simple,new String[]{"name","tel"},new int[]{R.id.name,R.id.tel});
	//上面的最后一个参数 对应的View只能是TextView(因为系统内部实现针对的是它),否则:
		adapter.setViewBinder(new ViewBinder(){//使ImageView的图片成功显示
					@Override
					public boolean setViewValue(View view, Object data,
							String textRepresentation) {
						if(view instanceof ImageView && data instanceof Bitmap){
							ImageView imgV=(ImageView) view;
							imgV.setImageBitmap((Bitmap)data);
							return true;
						}
						return false;
					}
		});

将布局xml文件变成view对象(打气筒):

//创建打气筒
1. LayoutInflater inflater = getLayoutInflater();  //调用Activity的getLayoutInflater()
2. LayoutInflater localinflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);//
3. LayoutInflater inflater = LayoutInflater.from(context);
public View inflate (int resource, ViewGroup root)
注意:如果root被提供的话,在把新生成的View连接到root后,返回root.否者返回的是新生成的View
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
注意:如果root被提供而且attachToRoot为TRUE的话,在把新生成的View连接到root,返回root。如果root被提供但attachToRoot为FALSE的话,root只是把它的LayoutParams参数给新生成的View用,不会把新生成的View连接到root,当然返回的是新生成的View。
4. View view = View.inflate(context, resource, root);	//直接用View的方法

Activity的对话框(以id来识别):

onCreateDialog(id) //只为初始化(只调用一次),这时要重写
	onPrepareDialog(dialog,id) //要show时,就会调用
	showDialog(id) //show哪个

删除当前进程(也就是退出当前程序):

android.os.Process.killProcess(android.os.Process.myPid());

退出Activity:

Activity.finish();
System.exit(0);

onPrepareOptionsMenu(Menu menu)是在手机点击menu键时调用的

ContextMenu类似右键快捷键:

registerForContextMenu(mB); //参数为View,长按弹出菜单 (在onLongClick()方法中返回值为false时)

Activity.onCreateContextMenu() //跟上面搭配时,一般要重写

在状态栏发送通知:

NotificationManager nm=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); //申请服务

Notification ntf=new Notification(R.drawable.ic_launcher, "来了一个通知...", System.currentTimeMillis());

Intent intent=new Intent(MainActivity.this,TurnActivity.class); //点击通知后往哪跳转

PendingIntent pi=PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);

ntf.setLatestEventInfo(getApplicationContext(), "测试" , "这是一个通知,测试中...", pi); //定义通知的消息

nm.notify(1, ntf);

通知的其他特效:

1.使用默认声音

notification.defaults |= Notification.DEFAULT_SOUND;

2.指定一个文件,作为声音

notification.sound = Uri.parse("file:///mnt/sdcard/aa.mp3");

3.当点击notification window时,清除notification信息

notification.flags |= Notification.FLAG_AUTO_CANCEL;

4.不希望被从notification window清除

notification.flags 加上 Notification.FLAG_NO_CLEAR;

5.手机震动效果

需要声明一个权限:

1)使用系统默认的震动效果

notification.defaults |= Notification.DEFAULT_VIBRATE;

2)使用自定义的震动效果

long[] vibrate = {0,100,200,300};

notification.vibrate = vibrate; //添加震动,参数(毫秒)第一个是开始时间,后一个是结束时间,以此反复

查看联系人列表

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts"));

//Intent intent = new Intent(Intent.ACTION_VIEW,ContactsContract.Contacts.CONTENT_URI);

startActivity(intent);

查看某一个联系人

Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts/190"));

//Intent intent = new Intent(Intent.ACTION_VIEW,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));

startActivity(intent);

Intent intent = new Intent(Intent.ACTION_EDIT,Uri.parse("content://com.android.contacts/contacts/190"));

//Intent intent = new Intent(Intent.ACTION_EDIT,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));

startActivity(intent);

查看并得到联系人信息(重写onActivityResult方法):

protected void onActivityResult(int requestCode, int resultCorede, Intent data) {

if(requestCode==FOR_CONTACT_ID){

if(resultCorede==RESULT_OK){

Uri uri=data.getData();

Cursor c1=getContentResolver().query(uri, null, null, null, null);

if(c1.moveToFirst()){

String id=c1.getString(c1.getColumnIndex(ContactsContract.Contacts._ID)); //得到返回的联系人ID

String name=c1.getString(c1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); //得到返回的联系人名字

nameEt.setText(name);

//这里需要注意的是,下面要得到的电话号码跟之前的不是一个表,而且要得到电话 需要添加权限:READ_CONTACTS

Cursor c2=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);

if(c2.moveToFirst()){

String phone=c2.getString(c2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));

phoneEt.setText(phone);

}

}

}

}

}

Intent定义的内容

在Android参考文档中,对Intent的定义是执行某操作的一个抽象描述。

(1)Action,也就是要执行的动作

(2)Data,也就是执行动作要操作的数据

(3)type(数据类型)

(4)category(类别)

(5)component(组件)

(6)extras(附加信息)

Intent--type(数据类型),显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,

但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

Intent intent = new Intent(Intent.ACTION_VIEW);

intent.setDataAndType(Uri.parse("file:///mnt/sdcard/a.pdf"),"application/pdf");

startActivity(intent);

Intent--component(组件),指定Intent的的目标组件的类名称。

如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。

Intent intent = new Intent();

ComponentName component = new ComponentName(getApplicationContext(), SecondActivity.class);

intent.setComponent(component);

startActivity(intent);

直接Intent:指定了component属性的Intent;(调用setComponent(ComponentName)或者setClassName(Context, Class)来指定)。

隐式Intent(Explicit Intents)和Intent Filter(Implicit Intents)进行比较时的三要素是Intent的动作、数据以及类别;

(隐式Intent:指的是在Intent intent = new Intent()时的java代码,而Intent filter是在androidManifest.xml文件中定义的。)

隐式启动:

Intent intent = new Intent();

intent.setAction("com.anjoyo.myfirsttest");

startActivity(intent);

intent-filter配置:

android系统的四大组件:

Activity、Service、BroadcastReceiver、ContentProvider

intent-filter:

一条元素至少应该包含一个,否则任何Intent请求都不能和 该匹配。

元素指定了希望接受的Intent请求的数据URI和数据类型,URI被分成三部分来进行匹配:scheme,authority和path。

如:百度一下,你就知道//http就是schema

tel:1390023232 //tel就是schema

file:///mnt/sdcard/Picture/xx.jpg //file就是schema

如何获取 res 中的资源:

主要类:Resources(android.content.res包)

Resources r = this.getContext().getResources();

主要方法:

getXXXX()

例如:

int getColor(int id)

Drawable getDrawable(int id)

String getString(int id) 直接获取res中存放的资源

String[] getStringArray(int id)//获取一个String数组

InputStream openRawResource(int id) //获取资源的数据流,读取资源数据

void parseBundleExtras(XmlResourceParser parser, Bundle outBundle)从XML文件中获取数据

定义了TransitionDrawable的使用:

http://schemas.android.com/apk/res/android">

可以在layout布局中,设置ImageView的background属性:

android:background="@drawable/mydrawable"

在Activity代码中

Drawable d = getResources().getDrawable(R.drawable.mydrawable);

TransitionDrawable td = (TransitionDrawable)d;

td.startTransition(2000);//实现两张图片间切换

如何自定义一个View

step1.

写一个类,继承View,或者你要扩展那个控件类

step2.提供构造方法:

有三个:

public View(Context context) {}

//构造函数往往用在new xxxView()中后边两种构造方法,是由系统调用。它自动把xml属性赋值给AttributeSet

public View(Context context, AttributeSet attrs) {}

public View(Context context, AttributeSet attrs, int defStyle){}

step3.

方式A.在layout的xml文件中,要写全包名,例如:

方式B.在java代码中直接new,例如:CustomView cv = new CustomView(this);

在自定义View里,ShapeDrawable使用,如画一个椭圆

protected void onDraw(Canvas canvas) {//重写方法

ShapeDrawable sd = new ShapeDrawable(new OvalShape());

Paint paint = sd.getPaint();

paint.setColor();

sd.setBounds(10, 10, 300+10, 100+10);

sd.draw(canvas);

}

NinePatchDrawable:

NinePatchDrawable 绘画的是一个可以伸缩的位图图像,

Android会自动调整大小来容纳显示的内容。

NinePatchDrawable是一个标准的PNG图像,它包括额外的1个像素的边界,你必须保存它后缀为.9.png,并且保持到工程的res/drawable目录中。

Android提供绘制工具,在sdk/tools/draw9patch.bat

Bitmap和BitmapFactory:

要获取位图信息,比如位图大小、像素、density、透明度、颜色格式等,获取得到Bitmap就迎刃而解了。

方式1: 建立空的Bitmap

Bitmap vBitmap=Bitmap.createBitmap(vWidth,vHeight,);

方式2: 取得Resource 的Bitmap

Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

方式3: 取得图档的Bitmap

Bitmap vBitmap=BitmapFactory.decodeStream(vContentResolver.openInputStream(uri));

这里只是辅助说明以下2点:

1. 在Bitmap中对RGB颜色格式使用Bitmap.Config定义,仅包括ALPHA_8、ARGB_4444、ARGB_8888、RGB_565,缺少了一些其他的,比如说RGB_555,在开发中可能需要注意这个小问题;

2. Bitmap还提供了compress()接口来压缩图片,不过Android SDK只支持PNG、JPG格式的压缩;其他格式的需要Android开发人员自己补充了

在Android中,把Canvas当做画布,可以在画布上绘制我们想要的任何东西。

方法:

clipXXX 裁剪,通过Path, Rect ,Region 的不同组合,几乎可以支持任意形状的裁剪区域。如: ClipPath, ClipRect,ClipRegion

drawXXX 绘制,可绘制图片,图形等。如:drawBtimap、drawLine

save() 用来保存canvas状态的。可以得到一个返回值,是用来确定保存时间的。

使用restoreToCount()方法时可以把此值当参数传递,可以还原到指定的保存时间。

restore() 用来恢复canvas状态的,还原到上一次save()时的状态。

translate(float dx,float dy); 移动canvas和它的原点到不同的位置上。默认原点坐标为(0,0)

参数:dx,左右偏移量(正数是向右移动)

dy,上下偏移量(正数是向下移动)

rotate(float degrees); 以原点为中心对canvas旋转。默认原点坐标为(0,0)参数:degrees 旋转弧度

scale(float sx, float sy); 增减图形在canvas中的像素数目,对形状,位图进行缩小或者放大。

参数:sx,横轴缩放大小

sy,数轴缩放大小

scale(float sx, float sy, float px, float py); //px,设置原点的位置(与rotate中的px正好相反,正数是向左移动)

py,设置原点的位置(与rotate中的py正好相反,正数是向上移动)

Paint类包含样式和颜色有关如何绘制几何形状,文本和位图的信息。

Canvas是一块画布,具体的文本和位图如何显示,这就是在Paint类中定义了。

Paint的功能:

字体、大小(TextSize)、颜色 (TextColor)、对齐方式(TextAlign)、粗体(Bold)、斜体(Italic)、下划线(Underline)等

字体类型:Typeface类--(BOLD,BOLD_ITALIC,ITALIC,NORMAL)

使用Paint显示String

Paint p = new Paint();

String familyName = 宋体;

Typeface font = Typeface.create(familyName,Typeface.BOLD);

p.setColor();

p.setTypeface(font);

p.setTextSize(22);

canvas.drawText(mstrTitle,0,100,p);

对于Android游戏开发或者说2D绘图中来讲Path 路径可以用强大这个词来形容。在Photoshop中我们可能还记得使用钢笔工具绘制路径的方法。

Path路径类在位于 android.graphics.Path中,Path的构造方法比较简单,如下

Path cwj=new Path(); //构造方法

下面我们画一个封闭的原型路径,我们使用Path类的addCircle方法

cwj.addCircle(10,10,50,Direction.CW); //参数一为x轴水平位置,参数二为y轴垂直位置,第三个参数为圆形的半径,最后是绘制的方向,

//CW为顺时针方向,而CCW是逆时针方向 (Clock Wise)(Counter Close Wise)

特效-Matrix,都是针对在Canvas

Matrix的操作,总共分为translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种

Matrix 提供set, post和pre三种操作方式,除了translate,其他三种操作都可以指定中心点。

set是直接设置Matrix的值,每次set一次,整个Matrix的数组都会变掉。

post是后乘,当前的矩阵乘以参数给出的矩阵。可以连续多次使用post,来完成所需的整个变换。

例如,要将一个图片旋转30度,然后平移到(100,100)的地方,那么可以这样做:

Matrix m = new Matrix();

m.postRotate(30);

m.postTranslate(100, 100);

pre是前乘,参数给出的矩阵乘以当前的矩阵。所以操作是在当前矩阵的最前面发生的。

例如上面的例子,如果用pre的话,就要这样:

Matrix m = new Matrix();

m.setTranslate(100, 100);

m.preRotate(30);

旋转、缩放和倾斜都可以围绕一个中心点来进行,如果不指定,默认情况下,是围绕(0,0)点来进行。

特效-Shader,都是针对在Canvas

Android中提供了Shader类专门用来渲染图像以及一些几何图形

Shader类的使用,都需要先构建Shader对象,然后通过Paint的setShader方法设置渲染对象,然后设置渲染对象,然后再绘制时使用这个Paint对象即可。

Shader shader = new BitmapShader(…..)

Shader shader = new LinearGradient(…..)

Paint paint = new Paint();

Paint.setShader(shader);

Shader下面包括几个直接子类,分别是:

BitmapShader 主要用来渲染图像,

LinearGradient 用来进行线性渲染,

RadialGradient 用来进行环形渲染,

SweepGradient 用来进行梯度渲染,

ComposeShader 则是一个 混合渲染,可以和其它几个子类组合起来使用。

Tween动画:

Android平台提供了两类动画,分别是Tween动画和Frame动画。

Tween通过场景里的对象不断的进行图片的变换,比如平移、渐变、缩放、旋转等来产生动画效果;

Frame动画叫做顺序播放实现做好的图像和电影类似。另外加上gif动画,因为如果直接使用Bitmap或其他方法直接调用gif图片资源的话,显示的是静态的,如果要做成动态的,就需要一些其他的方法来实现。

Tween动画分类:

Alpha:渐变透明度动画

Scale:渐变尺寸伸缩动画

Translate:画面转换位置移动动画

Rotate:画面转移旋转动画

有两种方式(java,xml):

java:

AlphaAnimation anim = new AlphaAnimation(0,1);

anim.setDuration(3000);

imageView.startAnimation(anim);

xml:

res/anim(必须在这里,文件夹名称必须这样)

http://schemas.android.com/apk/res/android"

android:fromAlpha="0.0"

android:toAlpha="1.0"

android:duration="2000"

>

Animation animation = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.alpha);

imageView.startAnimation(animation);

ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, floatXValue, int pivotYType, float pivotYValue)

功能:创建一个渐变尺寸伸缩动画

参数:fromX,toX分别是起始和结束时x坐标上的伸缩尺寸。

fromY,toY分别是起始和结束时ye坐标上的伸缩尺寸。

pivotXValue,pivotYValue分别为伸缩动画相对于x,y坐标开始的位置,

pivotXType,pivotYType分别为x,y的伸缩模式。

Animation anim = new ScaleAnimation(0, 1, 0, 1); //相对于(0,0)位置

Animation anim = new ScaleAnimation(1.0f,0.0f,1.0f,0.0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f); //相对与自身中心位置

anim.setFillAfter(true);是否保持动画后的状态,true表示保持

*****重点理解

Animation.RELATIVE_TO_SELF //表示相对自身 0.5f 表示中心

Animation.ABSOLUTE //表示一个固定的点 比如(300,300),表示在x轴为300px,y轴为300px的点为相对点

Animation.REALTIVE_TO_PARENT //表示相对父控件 0.5f表示父控件的一半

.xml

以指定位置(300,300)为中心点:

android:pivotX="300"

android:pivotY="300"

通过%来表示相对于自身什么位置:

android:pivotX="50%"

android:pivotY="50%"

通过p表示相对于父控件什么位置:

android:pivotX="50%p"

android:pivotY="100%p"

指定速度变化过程:

android:interpolator="@android:anim/accelerate_decelerate_interpolator"

动画组合Set:

xml:


			
			
		

监听Animation状态的事件AnimationListener

启动Animation两种方式

1. imageView.startAnimation(anim);

2. imageView.setAnimation(anim);

anim.start();

Frame动画:

方式一,java的实现:

private int[] images = {R.drawable.pic1,R.drawable.pic2,R.drawable.pic3,R.drawable.pic4};

final AnimationDrawable animDrawable = new AnimationDrawable();

for(int i=0;i<4;i++){

animDrawable.addFrame(getResources().getDrawable(images[i]), 80);

//以下方式要求是文件命名要遵循一定规律,方便递归查找。

//int resId = getResources().getIdentifier("pic"+(i+1), "drawable", "com.anjoyo.animation2");

//animDrawable.addFrame(getResources().getDrawable(resId), 500);

}

image.setBackgroundDrawable(animDrawable);

animDrawable.setOneShot(false); //是否只动画一次

animDrawable.start();

方式二,xml的实现:

定义:(必须在res/drawable)

http://schemas.android.com/apk/res/android"

android:oneshot="false">

使用1:

AnimationDrawable d = (AnimationDrawable) getResources().getDrawable(R.anim.frame);

image.setBackgroundDrawable(d);

使用2,在xml中使用:

android:background="@drawable/frame"

/>

AnimationDrawable d = (AnimationDrawable) image.getBackground();

d.start();

GridView:网格,跟ListView差不多,也是用Adapter添加数据。

android:id="@+id/gv"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:columnWidth="60dp"

android:numColumns="3"

android:verticalSpacing="10dp"

android:horizontalSpacing="15dp"

android:stretchMode="columnWidth"

android:gravity="center"

/>

Service:Android系统的后台服务组件(需要在AnroidManifest.xml文件配置service),适用于开发无界面、长时间运行的应用功能。

没有用户界面,比Activity 的优先级高,不会轻易被Android系统终止;

即使Service被系统终止,在系统资源恢复后Service也将自动恢复运行状态;

用于进程间通信(Inter Process Communication,IPC),解决两个不同Android应用程序进程之间的调用和通讯问题

启动service://隐式启动service,类似Activity的隐式启动

Intent intent = new Intent(getApplicationContext(),MyFirstService.class);

startService(intent);

停止service

Intent intent = new Intent(getApplicationContext(),MyFirstService.class);

stopService(intent);

MediaRecorder:录音:

在recorder.stop()后,要释放资源recorder.release();

MediaRecorder recorder = new MediaRecorder();

//声音源为话筒

recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

//设置输出格式

recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);

//音频编码

recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);

recorder.setOutputFile("/mnt/sdcard/record_"+(new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()))+".amr");

//开始录音

recorder.prepare();

recorder.start();

权限:

注意:

setAudioEncoder()必须在setOutputFormat()之后运行。

File sdcardFile = Environment.getExternalStorageDirectory();//得到sdcard根文件夹,因为有的手机sdcard路径就是/sdcard/

TelephonyManager监听电话状态:(要用到录音功能)

step1.获取TelephonyManager对象

TelephonyManager teleMan = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

teleMan.listen(new MyPhoneStateListener(this), PhoneStateListener.LISTEN_CALL_STATE);

step2.写那个类MyPhoneStateListner,实现PhoneStateListener接口

public class MyPhoneStateListener extends PhoneStateListener {

public void onCallStateChanged(int state, String incomingNumber) {

switch (state) {

case TelephonyManager.CALL_STATE_OFFHOOK:

try {

recorder.prepare();

recorder.start();

} catch (Exception e) {

e.printStackTrace();

}

break;

case TelephonyManager.CALL_STATE_IDLE:

if(isRecoder){

recorder.stop();

mr.release();

}

break;

}

}

}

step3.manifest.xml文件中声明权限

bind service:绑定服务:

通过服务链接(ServiceConnection)或直接获取Service中状态和数据信息服务链接能够获取Service的对象,因此绑定Service的组件可以调用Service中的实现的函数;

使用Service的组件通过Context.bindService()建立服务链接,通过Context.unbindService()停止服务链接;

同一个Service可以绑定多个ServiceConnection(服务链接),这样可以同时为多个不同的组件提供服务;

如何绑定:

Intent intent = new Intent(context,MyService.class);

ServiceConnection conn = new ServiceConnection(){

public void onServiceDisconnected(ComponentName name) {

Log.i("Service", "onServiceDisconnected===");

}

public void onServiceConnected(ComponentName name, IBinder service) {

Log.i("Service", "onServiceConnected===");

}

}

/*

**第3个参数Context.BIND_AUTO_CREATE表明只要绑定存在,就自动建立

**Service;同时也告知Android系统,这个Service的重要程度与调用者相同,

**除非考虑终止调用者,否则不要关闭这个Service

*/

context.bindService(intent,conn,Context.BIND_AUTO_CREATE);

解除绑定:

context.unBindService(conn);

注意:

1. unbindService(conn)//不可以多次调用

2. 如果onUnbind()函数的返回true,则表示在调用者绑定新服务时,onRebind()函数将被调用

3. 取消绑定仅需要使用unbindService()方法,并将ServiceConnnection传递给unbindService()方法

4. 关于ServiceConnection的两个方法:

当连接上service时,会调用onServiceConnected方法

当连接上后,service被后台停止,那么此时会调用onServiceDisconnected方法

5. unbindService()方法成功后,系统并不会调用onServiceDisconnected(),因为onServiceDisconnected()仅在意外断开绑定时才被调用

绑定Service的生命周期:

绑定:如果service没被创建,那么调用一次onCreate(),然后调用onBind(),多次绑定时,不会多次调用onBind()

解除绑定:调用onUnbind(),然后onDestory().不可以多次调用unbindService()方法解除绑定。

Service的启动方式和绑定方式的结合:

这两种使用方法并不是完全独立的,在某些情况下可以混合使用;

以MP3播放器为例:

在后台的工作的Service通过Context.startService()启动某个特定音乐播放,

但在播放过程中如果用户需要暂停音乐播放,则需要通过Context.bindService()获取服务链接和Service对象,

进而通过调用Service的对象中的函数,暂停音乐播放过程,并保存相关信息。

在这种情况下,如果调用Context.stopService()并不能够停止Service,需要在所有的服务链接关闭后,Service才能够真正的停止

生命周期:(绑定了就必须要先解绑后才能停止)

第一次点击:不管是startService还是bindService,如果service还未存在,那么会调用onCreate,之后如果是startService那么调用onStartCommand(),如果是bindService那么会调用onBind()

之后:如果再调startService(),那么会调用onStartCommand();如果再调用bindService那么如果第一次点击是bindService,那么就不会调用onBind(),否则什么方法都不会被调用。

当bindService后,不能stopService,需要通过unBindService()来解除绑定。

只是startService()后,不可以通过unBindService()来销毁service

注意:

service和Activity处于同一个线程。

分享到:

  admin

注册时间:

网站:0 个   小程序:3 个  文章:0 篇

  • 462

    网站

  • 9

    小程序

  • 3610

    文章

  • 113

    会员

赶快注册账号,推广您的网站吧!
热门网站
最新入驻小程序

跳一跳2022-08-22

跳一跳是微信开发的一款小游戏,有

数独大挑战2018-06-03

数独一种数学游戏,玩家需要根据9

答题星2018-06-03

您可以通过答题星轻松地创建试卷

全阶人生考试2018-06-03

各种考试题,题库,初中,高中,大学四六

运动步数有氧达人2018-06-03

记录运动步数,积累氧气值。还可偷

每日养生app2018-06-03

每日养生,天天健康