首页 文章 精选 留言 我的

精选列表

搜索[网站开发],共10000篇文章
优秀的个人博客,低调大师

Android UI开发第七篇之Android Gallery

新建项目 ② 定义layout外部resource的xml文件,用来改变layout的背景 <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="Gallery"> <attr name="android:galleryItemBackground" /> </declare-styleable> <!-- 定义layout 外部resource 的xml 文件,用来改变layout 的背景图。 --> </resources> 复制代码 ③ 修改main.xml布局,添加一个Gallery和一个ImageView <?xml version="1.0" encoding="utf-8"?> <AbsoluteLayout android:id="@+id/widget_absolutelayout" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" > <Gallery android:layout_width="fill_parent" android:layout_height="143px" android:layout_x="0px" android:layout_y="51px" android:id="@+id/Gallery_preView"> </Gallery> <ImageView android:layout_width="239px" android:layout_height="218px" android:layout_x="38px" android:layout_y="184px" android:id="@+id/ImageView_photo"> </ImageView> </AbsoluteLayout> 复制代码 ④ 新建一个myImageAdapter类--Gallery的适配器,它继承于BaseAdapter类. package zyf.Ex_Ctrl_10ME; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; public class myImageAdapter extends BaseAdapter { @Override public int getCount() { // TODO Auto-generated method stub return 0; } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub return null; } } 复制代码 ⑤ 修改mainActivity.java,添加Gallery相关操作 package zyf.Ex_Ctrl_10ME; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; public class Ex_Ctrl_10ME extends Activity { /** Called when the activity is first created. */ /*定义要使用的对象*/ privateGallerygallery; private ImageView imageview; private myImageAdapter imageadapter; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); imageadapter=new myImageAdapter(this); /* 通过findViewById 取得 资源对象*/ gallery=(Gallery)findViewById(R.id.Gallery_preView); imageview=(ImageView)findViewById(R.id.ImageView_photo); /*给Gallery设置适配器 把Ex_Ctrl_10ME类传入参数*/ gallery.setAdapter(imageadapter); /*设置Gallery的点击事件监听器*/ gallery.setOnItemClickListener(newGallery.OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { // TODO Auto-generated method stub /*显示该图片是几号*/ Toast.makeText(Ex_Ctrl_10ME.this, "这是图片:"+position+"号", Toast.LENGTH_SHORT).show(); /*设置大图片*/ imageview.setBackgroundResource(imageadapter.myImageIds[position]); } }); } } 复制代码 ⑥ 修改myImageAdapter.java文件,实现相簿浏览效果 package zyf.Ex_Ctrl_10ME; import android.content.Context; import android.content.res.TypedArray; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Gallery; import android.widget.ImageView; public class myImageAdapter extends BaseAdapter{//自定义的类变量 /*变量声明*/ int mGalleryItemBackground; private Context context;//上下文 /* 构建一Integer array 并取得预加载Drawable 的图片id */ public Integer[] myImageIds = { R.drawable.photo1, R.drawable.photo2, R.drawable.photo3, R.drawable.photo4, R.drawable.photo5, R.drawable.photo6, }; /*自定义的构造方法*/ public myImageAdapter(Context context) { // TODO Auto-generated constructor stub this.context=context; /* * 使用在res/values/attrs.xml 中的<declare-styleable>定义 的Gallery属性. */ TypedArray typed_array=context.obtainStyledAttributes(R.styleable.Gallery); /* 取得Gallery属性的Index id */ mGalleryItemBackground=typed_array.getResourceId(R.styleable.Gallery_android_galleryItemBackground, 0); /* 让对象的styleable 属性能够反复使用 */ typed_array.recycle(); } /* 重写的方法getCount,返回图片数目 */ @Override public int getCount() { // TODO Auto-generated method stub return myImageIds.length; } /* 重写的方法getItemId,返回图像的数组id */ @Override public Object getItem(int position) { // TODO Auto-generated method stub return position; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } /* 重写的方法getView,返回一View 对象 */ @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub /* 产生ImageView 对象 */ ImageView imageview = new ImageView(context); /* 设置图片给imageView 对象 */ imageview.setImageResource(myImageIds[position]); /* 重新设置图片的宽高 */ imageview.setScaleType(ImageView.ScaleType.FIT_XY); /* 重新设置Layout 的宽高 */ imageview.setLayoutParams(newGallery.LayoutParams(128, 128)); /* 设置Gallery背景图 */ imageview.setBackgroundResource(mGalleryItemBackground); /* 返回imageView 对象 */ return imageview; } } 复制代码 http://www.devdiv.com/home.php?mod=space&uid=14682&do=blog&id=3860 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/817368,如需转载请自行联系原作者

优秀的个人博客,低调大师

android开发教程之使用线程实现视图平滑滚动示例

最近一直想做下拉刷新的效果,琢磨了好久,才走到通过onTouch方法把整个视图往下拉的步骤,接下来就是能拉下来,松开手要能滑回去啊。网上看了好久,没有找到详细的下拉刷新的例子,只有自己慢慢琢磨了。昨天和今天,研究了两天,下拉之后回滚回去的效果终于今天做出来了!开心。现在来分享下我的实现方法和一些心得体会吧。 我看了网上一个大神的例子,发现是在onTouch里面使用View的scrollTo(int, int)方法,来使整个视图往下滚动的,我尝试了使用setTranslationY()来对视图进行回滚,第一次是没问题的,但多滚动几次之后,整个视图实际上已经到了非常“高”的地方了,要拉很长的距离才能看到内容。所以回滚也必须使用scrollTo(int, int)方法来操作。 但scrollTo(int, int)执行是瞬间的,方法名讲是滚动到,实际上就是“瞬移到”某个位置,因此需要一步一步的去瞬移它,让它看上去是滚过去的…… 因为等下要去跑步了,还有就是也没有什么很多的要点需要讲解,我就直接上代码给大家看,注释都写好了,要点会单独提一下,更详细的讲解与心得就等着我哪天把下拉刷新实现了吧。 复制代码代码如下: /** * @desc 平滑滚动 * @param v 需要操控的视图 * @param fromY 起始Y坐标 * @param toY 终止Y坐标 * @param fps 帧率 * @param durtion 动画完成时间(毫秒) * */ private void smoothScroll(View v, int fromY, int toY, int fps, long durtion) { smoothScrollThread = new SmoothScrollThread(v, fromY, toY, durtion, fps); smoothScrollThread.run(); } /** * @desc 平滑滚动线程,用于递归调用自己来实现某个视图的平滑滚动 * */ class SmoothScrollThread implements Runnable { //需要操控的视图 private View v = null; //原Y坐标 private int fromY = 0; //目标Y坐标 private int toY = 0; //动画执行时间(毫秒) private long durtion = 0; //帧率 private int fps = 60; //间隔时间(毫秒),间隔时间 = 1000 / 帧率 private int interval = 0; //启动时间,-1 表示尚未启动 private long startTime = -1; /减速插值器 private DecelerateInterpolator decelerateInterpolator = null; /** * @desc 构造方法,做好第一次配置 * */ public SmoothScrollThread(View v, int fromY, int toY, long durtion, int fps) { this.v = v; this.fromY = fromY; this.toY = toY; this.durtion = durtion; this.fps = fps; this.interval = 1000 / this.fps; decelerateInterpolator = new DecelerateInterpolator(); } @Override public void run() { //先判断是否是第一次启动,是第一次启动就记录下启动的时间戳,该值仅此一次赋值 if (startTime == -1) { startTime = System.currentTimeMillis(); } //得到当前这个瞬间的时间戳 long currentTime = System.currentTimeMillis(); //放大倍数,为了扩大除法计算的浮点精度 int enlargement = 1000; //算出当前这个瞬间运行到整个动画时间的百分之多少 float rate = (currentTime - startTime) * enlargement / durtion; //这个比率不可能在 0 - 1 之间,放大了之后即是 0 - 1000 之间 rate = Math.min(rate, 1000); //将动画的进度通过插值器得出响应的比率,乘以起始与目标坐标得出当前这个瞬间,视图应该滚动的距离。 int changeDistance = (int) ((fromY - toY) * decelerateInterpolator.getInterpolation(rate / enlargement)); int currentY = fromY - changeDistance; v.scrollTo(0, currentY); if (currentY != toY) { postDelayed(this, this.interval); } else { return; } } public void stop() { removeCallbacks(this); } } 一些要点: 1.使用线程的目的是可以递归的调用自己,在每个run()方法里只滚动一点点,这个一点点根据帧率和插值器来决定。 2.插值器实际上就是一个函数(数学里的函数),输入0-1之间的浮点数,输出0-1之间的浮点数,输出的曲线是什么样的,就看是什么插值器了,decelerate就是减速插值器了,在平面直角坐标系里面,x值均匀变化,y轴的变化越来越慢。 3.放大倍数(就是那里乘以1000)是为了提高精度,因为通过实践发现用已经过的毫秒数除以整个动画周期得出的结果是0.0 -> 0.0 -> 0.0 -> 0.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 1.0 -> 2.0 -> 2.0 -> 2.0,虽然是浮点数,但精度却莫名的保持在个位数上,乘以1000后,便会出现0-1000的均匀变化,这个时候去除以1000,便可得到0.000 - 1.000之间的均匀变化的数。 4.还有个很奇葩的是MotionEvent.getY()的值和scrollTo(int,int)的值貌似不是在同一个坐标系里面的。这个还有待进一步的分析和研究啊。 本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/6802339.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

【移动开发】Android中图片的多点触控和缩放

前几天做项目用到相机拍照,之后能对图片进行缩放,拖拽,在此我将其单独抽取出来,后面用到时直接拿来用就行了! 效果图: 注:这里不仅能按钮缩放,还能多点触摸缩放和拖拽功能! 1.布局: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 <? xml version = "1.0" encoding = "UTF-8" ?> < FrameLayout xmlns:android = "http://schemas.android.com/apk/res/android" android:id = "@+id/flayout_img_display" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:orientation = "vertical" > < LinearLayout android:id = "@+id/linearLayout_img_display" android:layout_width = "fill_parent" android:layout_height = "fill_parent" android:layout_gravity = "center" android:gravity = "center" > < ImageView android:id = "@+id/img_display" android:layout_width = "fill_parent" android:layout_height = "wrap_content" android:paddingBottom = "5.0dip" android:paddingTop = "5.0dip" android:scaleType = "matrix" /> </ LinearLayout > < RelativeLayout android:id = "@+id/relativeLayout1" android:layout_width = "fill_parent" android:layout_height = "wrap_content" > < Button android:id = "@+id/btn_min" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentBottom = "true" android:layout_alignParentLeft = "true" android:enabled = "false" android:text = "缩小" /> < Button android:id = "@+id/btn_out" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_alignParentBottom = "true" android:layout_alignParentRight = "true" android:text = "放大" /> </ RelativeLayout > </ FrameLayout > 2.就一个类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 import android.app.Activity; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PointF; import android.os.Bundle; import android.util.FloatMath; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnTouchListener; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; /** * 缩放图片界面 * @author ZHF * */ public class MainActivity extends Activity { public static final String TAG = "ImgDisplayActivity" ; //控件声明 private Button btnZoomin, btnZoomout; private ImageView imgDisPlay; private LinearLayout lLayoutDisplay; private FrameLayout fLayoutDisplay; private Bitmap bitmap; private int imgId = 0 ; private double scale_in = 0.8 ; //缩小比例 private double scale_out = 1.25 ; //放大比例 private float scaleWidth = 1 ; private float scaleHeight = 1 ; //模式:0:什么都不干;1:拖拽; 2:缩放 public static final int NONE = 0 ; public static final int DRAG = 1 ; public static final int ZOOM = 2 ; //声明触发的事件模式 private int mode = NONE; private Matrix matrix; //矩阵 private Matrix currMatrix; //当前矩阵 private PointF starPoint; private PointF midPoint; private float startDistance; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); //初始化 fLayoutDisplay = (FrameLayout) findViewById(R.id.flayout_img_display); lLayoutDisplay = (LinearLayout) findViewById(R.id.linearLayout_img_display); imgDisPlay = (ImageView) findViewById(R.id.img_display); btnZoomin = (Button) findViewById(R.id.btn_min); btnZoomout = (Button) findViewById(R.id.btn_out); matrix = new Matrix(); //保存拖拽变化 currMatrix = new Matrix(); // 当前的 starPoint = new PointF(); //开始点的位置 btnZoomin.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { zoomIn(); } }); btnZoomout.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { zoomOut(); //放大 } }); imgDisPlay.setImageResource(R.drawable.img); //给图片绑定监听器哦 imgDisPlay.setOnTouchListener( new ImageViewOnTouchListener()); } /**放大操作**/ private void zoomOut() { reSizeBmp(scale_out); btnZoomin.setEnabled( true ); } /**缩小操作**/ private void zoomIn() { reSizeBmp(scale_in); } /**接收传入的缩放比例实现缩放**/ private void reSizeBmp( double scale) { //缩放比例 scaleWidth = ( float ) (scaleWidth * scale); scaleHeight = ( float ) (scaleHeight * scale); Matrix matrix = new Matrix(); matrix.postScale(scaleWidth, scaleHeight); //设计缩放比例 imgDisPlay.setImageMatrix(matrix); } /**计算触摸实现缩放**/ final class ImageViewOnTouchListener implements OnTouchListener{ @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: //一只手指按下 Log.i(TAG, "一只手指按下" ); currMatrix.set(matrix); starPoint.set(event.getX(), event.getY()); mode = DRAG; break ; case MotionEvent.ACTION_POINTER_DOWN: //如果有一只手指按下屏幕,后续又有一个手指按下 // 两只手指按下 Log.i(TAG, "又有一只手指按下" ); startDistance = distance(event); //记下两点的距离 Log.i(TAG, startDistance+ "" ); if (startDistance > 5f) { //两个手指之间的最小距离像素大于5,认为是多点触摸 mode = ZOOM; currMatrix.set(matrix); midPoint = getMidPoint(event); //记下两个点之间的中心点 } break ; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { //拖拽模式 Log.i(TAG, "一只手指在拖拽" ); //开始--》结束点的距离 float dx = event.getX() - starPoint.x; float dy = event.getY() - starPoint.y; matrix.set(currMatrix); matrix.postTranslate(dx, dy); //移动到指定点:矩阵移动比例;eg:缩放有缩放比例 } else if (mode == ZOOM) { //缩放模式 Log.i(TAG, "正在缩放" ); float distance = distance(event); //两点之间的距离 if (distance > 5f) { matrix.set(currMatrix); float cale = distance / startDistance; matrix.preScale(cale, cale, midPoint.x, midPoint.y); //进行比例缩放 } } break ; case MotionEvent.ACTION_UP: //最后一只手指离开屏幕后触发此事件 case MotionEvent.ACTION_POINTER_UP: //一只手指离开屏幕,但还有一只手指在上面会触此事件 //什么都没做 mode = NONE; break ; default : break ; } imgDisPlay.setImageMatrix(matrix); //两只手指的缩放 return true ; } } /**计算两点之间的距离像素**/ private float distance(MotionEvent e) { float eX = e.getX( 1 ) - e.getX( 0 ); //后面的点坐标 - 前面点的坐标 float eY = e.getY( 1 ) - e.getY( 0 ); return FloatMath.sqrt(eX * eX + eY * eY); } /**计算两点之间的中心点**/ private PointF getMidPoint(MotionEvent event) { float x = (event.getX( 1 ) - event.getX( 0 )) / 2 ; float y = (event.getY( 1 ) - event.getY( 0 )) / 2 ; return new PointF(x,y); } } ok!主要的算法就在ImageViewOnTouchListener监听器当中,要考虑那三种情况(缩放、拖拽、什么都不干),另外需要注意的就是,单个手指和两个以上手指的情况。 源码下载:http://down.51cto.com/data/876165 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1252191,如需转载请自行联系原作者

优秀的个人博客,低调大师

【Android开发—智能家居系列】(四):UDP通信发送指令

思路回顾 【1】手机连接WIFI模块 【2】UDP通信对WIFI模块发送指令,以和WIFI模块保持连接状态 【3】UDP通信对WIFI模块发送指令,让其搜索可用的无线网,返回WIFI列表 【4】发送指令,让WIFI模块接入指定路由 【5】手机连接路由 【6】发送指令,获得WIFI模块的动态IP地址 UDP通信线程类 package com.jczb.smartlife.common; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketException; import java.net.UnknownHostException; import android.os.Handler; import android.os.Message; import com.jczb.smartlife.common.Tool; public class GetInfoThread extends Thread { private Handler handler; private DatagramSocket socket; private int msgType; private final String IP = "255.255.255.255";//广播地址 private int PORT = 26000; /** * 48899端口:C32x系列的端口,用户可以用AT指令更改 * 49000端口:除C32x系列,其他WIFI模块的端口 * 1902端口:有人掌控宝系列产品的端口 */ private int targetPort = 49000 ; private boolean receive = true; /** * * @param handler 传入监听此线程的Handler * @param intMsg 传入监听的消息类型 */ public GetInfoThread(Handler handler,int msgType) { this.handler = handler; this.msgType=msgType; init(); } public void init(){ try { socket = new DatagramSocket(null); socket.setBroadcast(true); socket.setReuseAddress(true); socket.bind(new InetSocketAddress(PORT)); } catch (SocketException e) { e.printStackTrace(); sendErrorMsg("Search Thread init fail"); return; } } public void run() { if (socket == null) { return; } try { byte[] data = new byte[1024]; //创建一个空的DatagramPacket对象 DatagramPacket revPacket = new DatagramPacket(data, data.length); while (receive) { //服务端接收数据 socket.receive(revPacket); if(null!=handler){ byte[] realData = new byte[revPacket.getLength()]; System.arraycopy(data, 0, realData,0, realData.length); Message msg =handler.obtainMessage(msgType,realData); handler.sendMessage(msg); } } } catch (Exception e) { e.printStackTrace(); socket.close(); } } public void close() { if (socket == null) return; socket.close(); } private void sendErrorMsg(String info){ } /** * 发送数据 * @param msg */ public void sendMsg(byte[] msg) { if (socket != null) { try { System.out.println("targetPort------------------->"+targetPort); DatagramPacket sendPacket = new DatagramPacket(msg, msg.length, InetAddress.getByName(IP), targetPort); socket.send(sendPacket); } catch (UnknownHostException e) { e.printStackTrace(); System.out.println("发送失败"); } catch (IOException e) { e.printStackTrace(); System.out.println("发送失败"); } } } public void setReceive(boolean receive) { this.receive = receive; } public void setTargetPort(int targetPort) { this.targetPort = targetPort; } public void setMsgType(int msgType){ this.msgType=msgType; } } 发送消息的线程类 /** * 发送消息的队列,每次发送数据时,只需要调用putMsg(byte[] data)方法 * * @author usr_liujinqi * */ private class SendMsgThread extends Thread { // 发送消息的队列 private Queue<byte[]> sendMsgQuene = new LinkedList<byte[]>(); // 是否发送消息 private boolean send = true; private GetInfoThread ss; public SendMsgThread(GetInfoThread ss) { this.ss = ss; } public synchronized void putMsg(byte[] msg) { // 唤醒线程 if (sendMsgQuene.size() == 0) notify(); sendMsgQuene.offer(msg); } public void run() { synchronized (this) { while (send) { // 当队列里的消息发送完毕后,线程等待 while (sendMsgQuene.size() > 0) { byte[] msg = sendMsgQuene.poll(); if (ss != null) ss.sendMsg(msg); } try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } public void setSend(boolean send) { this.send = send; } } 应用 【举例】发送搜索WIFI模块的指令 //1.用户获得温控器中WIFI模块的WIFI模块的IP地址,MAC地址,模块名称的指令 private final byte[] getInfoCode=new byte[]{(byte)0x48,0x46,0x2D,0x41,0x31,0x31,0x41,0x53,0x53,0x49,0x53,0x54,0x48,0x52,0x45,0x41,0x44}; public static final int REC_Module=0x04;//搜索WIFI模块的信息(包括IP、Mac、名称) //实例化一个线程,用户获得模块信息(IP,Mac,名称) //参数为监听为此线程的Handler,以及接收成功后,给Handler发送的消息类型 getInfoThread = new GetInfoThread(handler,Tool.REC_Module); getInfoThread.start(); //发送消息的线程 smt = new SendMsgThread(getInfoThread); smt.start(); //设置发送的目的端口号 getInfoThread.setTargetPort(Integer.parseInt("48899")); smt.putMsg(getInfoCode); WIFI模块在接收到指令后,就会回复信息,以下的Handler就是针对回复过来的信息进行解析处理等操作。 //处理消息的Handler private Handler handler= new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case Tool.REC_Module:// 解析接收到的数据 //设置发送的目的端口号 getInfoThread.setTargetPort(Integer.parseInt("48899")); getInfoThread.setMsgType(Tool.REC_OK); smt.putMsg(okCode); SetServer(); SetDHCP(); byte[] data = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTemp= Tool.bytesToHexString(data); //将十六进制的字符串去掉空格之后进行解析 String strdecode=Tool.DecodeHex(strTemp.replace(" ", "")); //取出IP,Mac地址,模块名称 decodeIP(strdecode); Toast.makeText(ConnectWifiActivity.this, "获得WIFI模块名称成功!"+ModuleName, Toast.LENGTH_SHORT).show(); break; case Tool.REC_Server: byte[] dataServer = (byte[])msg.obj; //将十进制的数据转化成十六进制数据 String strServer= Tool.bytesToHexString(dataServer); if("2b 6f 6b 0d 0a 0d 0a ".equals(strServer)){ Toast.makeText(ConnectWifiActivity.this, "设置服务器成功!", Toast.LENGTH_SHORT).show(); } break; case Tool.REC_SSID: byte[] dataSSID=(byte[])msg.obj; Tool.bytesToHexString(dataSSID); decodeData(dataSSID); break; case Tool.REC_AT: byte[] dataID = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTempID= Tool.bytesToHexString(dataID); //将十六进制的字符串去掉空格之后进行解析 String strdecodeID=Tool.DecodeHex(strTempID.replace(" ", "")); break; case Tool.REC_DHCP: byte[] dataDHCP = (byte[])msg.obj; //将十进制的数据转化成十六进制数据 String strDHCP= Tool.bytesToHexString(dataDHCP); if("2b 6f 6b 0d 0a 0d 0a ".equals(strDHCP)){ Toast.makeText(ConnectWifiActivity.this, "设置DHCP网络参数成功!", Toast.LENGTH_SHORT).show(); } break; default: byte[] data1 = (byte[]) msg.obj; //将十进制的数据转化成十六进制数据 String strTemp1= Tool.bytesToHexString(data1); Toast.makeText(ConnectWifiActivity.this, strTemp1, Toast.LENGTH_SHORT).show(); break; } } }; 总结 凡是需要对WIFI模块发送指令的,就需要用到上述的两个线程类,还有一个对返回信息进行处理的Handler。只是发送的指令的code不一样,如上述表示的是搜索WIFI模块的十六进制的指令。不管WIFI模块在AP模式下还是STA模式,通信的最开始步骤都是先搜索模块,然后获得它的IP和Mac之后,立即回复+ok指令,就可以保持连接状态。 本文转自 一点点征服 博客园博客,原文链接: http://www.cnblogs.com/ldq2016/p/6774195.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android开发学习笔记:Intent的简介以及属性的详解

一.Intent的介绍 Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。 二.Inten启动组件的方法 Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下: 组件名称 方法名称 Activity startActvity( ) startActivity( ) Service startService( ) bindService( ) Broadcasts sendBroadcasts( ) sendOrderedBroadcasts( ) sendStickyBroadcasts( ) 三.Intent的属性 Intent有以下几个属性: 动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。 1.Intent的Action属性 Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。 Constant Target component Action ACTION_CALL activity Initiate a phone call. ACTION_EDIT activity Display data for the user to edit. ACTION_MAIN activity Start up as the initial activity of a task, with no data input and no returned output. ACTION_SYNC activity Synchronize data on a server with data on the mobile device. ACTION_BATTERY_LOW broadcast receiver A warning that the battery is low. ACTION_HEADSET_PLUG broadcast receiver A headset has been plugged into the device, or unplugged from it. ACTION_SCREEN_ON broadcast receiver The screen has been turned on. ACTION_TIMEZONE_CHANGED broadcast receiver The setting for the time zone has changed. 下面是一个测试Action常量的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns: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="@string/hello" /> <Button android:text="测试Action属性" android:id="@+id/getBtn" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">测试Action属性</string> <stringname="app_name">IntentActionDemo</string> </resources> MainActivity.java packagecom.android.action.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtongetBtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); getBtn=(Button)findViewById(R.id.getBtn); getBtn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_GET_CONTENT);//设置IntentAction属性 intent.setType("vnd.android.cursor.item/phone");//设置IntentType属性 //主要是获取通讯录的内容 startActivity(intent);//启动Activity } }); } } 效果图: 2.Intent的Data属性 Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。 3.Intent的Category属性 Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。 Constant Meaning CATEGORY_BROWSABLE The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. CATEGORY_GADGET The activity can be embedded inside of another activity that hosts gadgets. CATEGORY_HOME The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed. CATEGORY_LAUNCHER The activity can be the initial activity of a task and is listed in the top-level application launcher. CATEGORY_PREFERENCE The target activity is a preference panel. 下面是一个回到Home界面的例子: main.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns: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="测试IntentCategory" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="转到Home界面" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,MainActivity!</string> <stringname="app_name">IntentCategoryDemo</string> </resources> MainActivity.java packagecom.android.category.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; publicclassMainActivityextendsActivity{ privateButtonbtn; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); btn=(Button)findViewById(R.id.Button1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); intent.setAction(Intent.ACTION_MAIN);//添加Action属性 intent.addCategory(Intent.CATEGORY_HOME);//添加Category属性 startActivity(intent);//启动Activity } }); } } 效果图: 4.Intent的Type属性 Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。 5.Intent的Compent属性 Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。 6.Intent的Extra属性 Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。 下面的例子在第一个Activity的EditText输入用户名,该年龄保存在Intent的Extras属性中。当单击Button时,会在第二个Activity中显示用户名。 first.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns: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="wrap_content" android:layout_height="wrap_content" android:text="请输入用户名" /> <EditText android:id="@+id/EditText1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="测试Extras属性" /> </LinearLayout> second.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/TextView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloWorld,FirstActivity!</string> <stringname="app_name">IntentExtrasDemo</string> </resources> FirstActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.EditText; publicclassFirstActivityextendsActivity{ privateButtonbtn; privateEditTextetx; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.first); btn=(Button)findViewById(R.id.Button1); etx=(EditText)findViewById(R.id.EditText1); btn.setOnClickListener(newOnClickListener(){ @Override publicvoidonClick(Viewv){ Intentintent=newIntent(); //设置Intent的class属性,跳转到SecondActivity intent.setClass(FirstActivity.this,SecondActivity.class); //为intent添加额外的信息 intent.putExtra("useName",etx.getText().toString()); //启动Activity startActivity(intent); } }); } } SecondActivity.java packagecom.android.extras.activity; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; importandroid.widget.TextView; publicclassSecondActivityextendsActivity{ privateTextViewtv; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //设置当前的Activity的界面布局 setContentView(R.layout.second); //获得Intent Intentintent=this.getIntent(); tv=(TextView)findViewById(R.id.TextView1); //从Intent获得额外信息,设置为TextView的文本 tv.setText(intent.getStringExtra("useName")); } } 注意:在添加第二个Activity SecondActivity的时候,要在AndroidManifest.xml里面添加上SecondActivity,具体如下,即是在15行</activity>的后面添加上16~18行的代码。如果不这样做,就会在模拟器上出现错误。 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.extras.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".FirstActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activityandroid:name=".SecondActivity" android:label="@string/app_name"> </activity> </application> </manifest> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/634411

优秀的个人博客,低调大师

【Android开发—智能家居系列】(三):手机连接WIFI模块

版权声明:本文为博主原创文章,未经博主允许不得转载。 目录(?)[+] 概述 实现连接WIFI的功能会用到一个工具类,源码可以点击链接下载。网上这些类似的工具类里的代码差不多是一样的。连接无线网主要有两个方法: 其中有一个Connect方法,还有一个connectSpecificAP方法,对于不需要密码就能链接的WIFI模块,我使用的是后者。 主要步骤 连接WIFI大致分为一下几个步骤: 【1】打开WIFI openWifi 【2】配置网络信息 createWifiInfo返回WIFiConfig 【3】添加配置好的网络并连接 int netID = mWifiManager.addNetwork(wifiConfig); boolean bRet = mWifiManager.enableNetwork(netID, false); 【4】判断连接是否成功 上面的enableNetWork方法返回成功并不能反映手机是否真的连接成功,所以还需要调用isConnect方法进行判断,针对自己的业务逻辑和场景,我又写了一个判断是否连接成功的方法:isWifiConnected的方法 应用 /** * 手机接入模块的WIFI网络——BLACKANTS */ private void ConnectDisplay(){ //获得消息对象 Message msg=mainHandler.obtainMessage(); //是否连接成功的一个标记 Boolean isConnected=false; //标志BLACKANTS的ScanResult是否存在,true存在,false不存在 Boolean isExist=false; //用户存放BLACKANTS的WIFI信息 ScanResult srWifiInfo=null; //声明一个用于临时存放SSID的变量 String strTempSSID; /******************以下一段代码主要是为了获得BLACKANTS的ScanResult(包括了它的SSID,BSSID,capabilities)*****************/ //扫描WIFI wifiAdmin.startScan(); //获得WIFI列表 List<ScanResult> lstWiFi= wifiAdmin.getWifiList(); //如果WIFI列表为空,则说明WIFI开关未打开,向Handler发送消息 if(lstWiFi==null || lstWiFi.size()==0){ msg.what=NotOpen; mainHandler.sendMessage(msg); return; } //如果列表存在,则对列表进行遍历 if(lstWiFi!=null & lstWiFi.size()>0){ //遍历列表,查看BLACKANTS是否存在 for(int i=0;i<lstWiFi.size();i++){ strTempSSID=lstWiFi.get(i).SSID; //如果存在,则退出For循环 if((DisplaySSID).equals(strTempSSID.trim()) ){ //修改标志位为存在 isExist=true; //将BLACKANTS的Wifi信息放入到变量srWifiInfo中 srWifiInfo=lstWiFi.get(i); break; } } } /******************以上一段代码主要是为了获得BLACKANTS的ScanResult(包括了它的SSID,BSSID,capabilities)*****************/ //默认是失败 msg.what=Failure; //如果存在,则让手机接入BLACKANTS-------------------V1.0 if(isExist){ if(wifiAdmin.connectSpecificAP(srWifiInfo)){ //判断是否连接上 if(wifiAdmin.isWifiConnected(InitActivity.this,DisplaySSID)){ msg.what=Success; } } } mainHandler.sendMessage(msg); } 附: 下载工具类(WIFIAdmin) 本文转自 一点点征服 博客园博客,原文链接: http://www.cnblogs.com/ldq2016/p/6774176.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android UI开发第五篇——自定义列表

自定义列表,设置列表背景、列表的列背景、列表的间隔线。 借鉴了一些前辈的代码。 MainActivity.class public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //绑定Layout里面的ListView ListView list = (ListView) findViewById(R.id.ListView01); //生成动态数组,加入数据 ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>(); for(int i=0;i<5;i++) { if(i==0){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", R.drawable.checked);//图像资源的ID map.put("ItemTitle", "个人信息"); map.put("LastImage", R.drawable.lastimage); listItem.add(map); }else if(i==1){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", R.drawable.c);//图像资源的ID map.put("ItemTitle", "修改密码"); map.put("LastImage", R.drawable.lastimage); listItem.add(map); }else if(i==2){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", R.drawable.d);//图像资源的ID map.put("ItemTitle", "网络设置"); map.put("LastImage", R.drawable.lastimage); listItem.add(map); }else if(i==3){ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", R.drawable.d);//图像资源的ID map.put("ItemTitle", "打印设置"); map.put("LastImage", R.drawable.lastimage); listItem.add(map); }else{ HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage", R.drawable.e);//图像资源的ID map.put("ItemTitle", "返回"); map.put("LastImage", R.drawable.lastimage); listItem.add(map); } } //生成适配器的Item和动态数组对应的元素 SimpleAdapter listItemAdapter = new SimpleAdapter(this,listItem,// 数据源 R.layout.list_items,//ListItem的XML实现 //动态数组与ImageItem对应的子项 new String[] {"ItemImage","ItemTitle", "LastImage"}, //ImageItem的XML文件里面的一个ImageView,两个TextView ID new int[] {R.id.ItemImage,R.id.ItemTitle,R.id.last} ); //添加并且显示 list.setAdapter(listItemAdapter); //添加点击 list.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { setTitle("点击第"+arg2+"个项目"); if(arg2 == 4){ MainActivity.this.finish(); } } }); //添加长按点击 list.setOnCreateContextMenuListener(new OnCreateContextMenuListener() { @Override public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) { menu.setHeaderTitle("长按菜单-ContextMenu"); menu.add(0, 0, 0, "弹出长按菜单0"); menu.add(0, 1, 0, "弹出长按菜单1"); } }); } //长按菜单响应函数 @Override public boolean onContextItemSelected(MenuItem item) { setTitle("点击了长按菜单里面的第"+item.getItemId()+"个项目"); return super.onContextItemSelected(item); } } main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffff" xmlns:android="http://schemas.android.com/apk/res/android"> <ListView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/ListView01" android:divider="@drawable/divider_color" android:dividerHeight="3dip" android:cacheColorHint="#00000000" /> </LinearLayout> list_item.xml <?xml version="1.0" encoding="utf-8"?> <RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:layout_height="wrap_content" android:paddingBottom="4dip" android:paddingLeft="12dip" android:paddingRight="12dip" android:background="@drawable/list_bg"> <ImageView android:paddingTop="12dip" android:layout_alignParentLeft="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/ItemImage" /> <TextView android:text="TextView01" android:layout_height="wrap_content" android:layout_marginTop="30px" android:textSize="20dip" android:paddingLeft="12dip" android:textColor="#000000" android:layout_width="fill_parent" android:id="@+id/ItemTitle" android:layout_toRightOf="@+id/ItemImage" /> <ImageView android:paddingTop="12dip" android:layout_marginTop="20px" android:layout_alignParentRight="true" android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/last" /> </RelativeLayout> http://www.devdiv.com/home.php?mod=space&uid=14682&do=blog&id=2888 http://www.devdiv.com/home.php?mod=space&uid=14682&do=blog&id=2888 http://www.devdiv.com/home.php?mod=space&uid=14682&do=blog&id=2888 http://www.devdiv.com/forum.php?mod=viewthread&tid=97913&page=1#pid591587 http://blog.csdn.net/zeng622peng/archive/2010/08/11/5804965.aspx http://www.devdiv.com/home.php?mod=space&uid=14682&do=blog&id=2888 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/817375 ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Java微服务开发指南 -- 使用Dropwizard构建微服务

使用Dropwizard构建微服务 Dropwizard的历史要早于Spring Boot和WildFly Swarm,它最早是在2011.12发布的v0.1.0版本,在本文编写的过程中,它已经发布了v0.9.2版本,而v1.0.0版本也在准备中了。Dropwizard是Coda Hale在Yammer公司时创立的,它旨在提升公司分布式系统的架构(现在叫:微服务)。虽然它最早被用来构建REST Web 服务,而现在它具备了越来越多的功能,但是它的目标始终是作为轻量化、为生产环境准备且容易使用的web框架。 目前Dropwizard已经发布了v1.1.0版本 Dropwizard与Spring Boot类似,也是构建微服务可选的工具,但是它显得比Spring Boot更加规范一些。它使用的组件一般不会做可选替换,而好处是可

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册