首页 文章 精选 留言 我的

精选列表

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

Android开发学习笔记:浅谈WebView

WebView(网络视图)能加载显示网页,可以将其视为一个浏览器。它使用了WebKit渲染引擎加载显示网页,实现WebView有以下两种不同的方法: 第一种方法的步骤: 1.在要Activity中实例化WebView组件:WebView webView = new WebView(this); 2.调用WebView的loadUrl()方法,设置WevView要显示的网页: 互联网用:webView.loadUrl("http://www.google.com"); 本地文件用:webView.loadUrl("file:///android_asset/XX.html");本地文件存放在:assets文件中 3.调用Activity的setContentView()方法来显示网页视图 4.用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面 5.需要在AndroidManifest.xml文件中添加权限,否则会出现Web page not available错误。<uses-permissionandroid:name="android.permission.INTERNET"/> 下面是具体例子: MainActivity.java packagecom.android.webview.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.KeyEvent; importandroid.webkit.WebView; publicclassMainActivityextendsActivity{ privateWebViewwebview; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); //实例化WebView对象 webview=newWebView(this); //设置WebView属性,能够执行Javascript脚本 webview.getSettings().setJavaScriptEnabled(true); //加载需要显示的网页 webview.loadUrl("http://www.51cto.com/"); //设置Web视图 setContentView(webview); } @Override //设置回退 //覆盖Activity类的onKeyDown(intkeyCoder,KeyEventevent)方法 publicbooleanonKeyDown(intkeyCode,KeyEventevent){ if((keyCode==KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){ webview.goBack();//goBack()表示返回WebView的上一页面 returntrue; } returnfalse; } 在AndroidManifest.xml文件中的17行添加权限 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.webview.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.INTERNET"/> </manifest> 效果图: 第二种方法的步骤: 1、在布局文件中声明WebView 2、在Activity中实例化WebView 3、调用WebView的loadUrl( )方法,设置WevView要显示的网页 4、为了让WebView能够响应超链接功能,调用setWebViewClient( )方法,设置 WebView视图 5、用WebView点链接看了很多页以后为了让WebView支持回退功能,需要覆盖覆盖Activity类的onKeyDown()方法,如果不做任何处理,点击系统回退剪键,整个浏览器会调用finish()而结束自身,而不是回退到上一页面 6、需要在AndroidManifest.xml文件中添加权限,否则出现Web page not available错误。 <uses-permission android:name="android.permission.INTERNET"/> 下面是具体的例子: MainActivity.java packagecom.android.webview.activity; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.KeyEvent; importandroid.webkit.WebView; importandroid.webkit.WebViewClient; publicclassMainActivityextendsActivity{ privateWebViewwebview; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); webview=(WebView)findViewById(R.id.webview); //设置WebView属性,能够执行Javascript脚本 webview.getSettings().setJavaScriptEnabled(true); //加载需要显示的网页 webview.loadUrl("http://www.51cto.com/"); //设置Web视图 webview.setWebViewClient(newHelloWebViewClient()); } @Override //设置回退 //覆盖Activity类的onKeyDown(intkeyCoder,KeyEventevent)方法 publicbooleanonKeyDown(intkeyCode,KeyEventevent){ if((keyCode==KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){ webview.goBack();//goBack()表示返回WebView的上一页面 returntrue; } returnfalse; } //Web视图 privateclassHelloWebViewClientextendsWebViewClient{ @Override publicbooleanshouldOverrideUrlLoading(WebViewview,Stringurl){ view.loadUrl(url); returntrue; } } } 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" > <WebView android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> </LinearLayout> 在AndroidManifest.xml文件中的17行添加权限 <?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.android.webview.activity" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <applicationandroid:icon="@drawable/icon"android:label="@string/app_name"> <activityandroid:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> <uses-permissionandroid:name="android.permission.INTERNET"/> </manifest> 效果图: 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/647456

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

实战:Android活动目录LiveFolder开发

活动目录(LiveFolder)是一种小型的应用层插件。它本身体现为桌面出现的图标,通过点击这些图标,将出现一个列表框,列表框中将显示数据信息。通过活动目录可以在不打开应用程序的情况下,在桌面就能查看其中的数据信息。 在Android的桌面中长按桌面或者选择菜单,进入增加活动目录的界面,可以将LiveFolder增加到桌面,LiveFolder的增加界面和运行效果如图8-4所示。 图8-4中左图为增加LiveFolder的界面,列表中的内容由各个应用程序实现的增加LiveFolder的入口决定。LiveFolder点击后不会启动Activity,而是在出现类似图8-4中右图的界面的对话框。这个对话框不是LiveFolder实现者的一部分,而是桌面程序提供的功能。对话框通常包含一个列表,LiveFolder实现者可以实现其中的每个项目显示的内容,还可以进一步实现每个内容被点击之后,出现的界面。如果仅仅出现活动目录列表项对话框,实际是LiveFolder实现者并没有提供运行的界面,而只是在桌面查看了其中的内容。 ▲图8-4 活动目录增加界面和运行效果(左:增加界面;中:Contacts活动目录; 右:Contacts活动目录的点击效果) LiveFolder的程序组成 LiveFolder插件的本质是一个特殊的Activity和一个特殊的ContentProvider。Activity需要支持特殊的Intent动作,负责创建LiveFolder,并通过URI关联到某个ContentProvider;ContentProvider负责提供LiveFolder中使用的各个项目的内容。 android.provider包的LiveFolders类定义活动目录的Activity和ContentProvider中的特殊内容。 1.LiveFolder的Activity 在Activity方面,LiveFolders类中的ACTION_CREATE_LIVE_FOLDER动作,实际表示的字符串为“android.intent.action.CREATE_LIVE_FOLDER”。接受这个Intent-filter的Activity,将被桌面程序选择作为可以创建LiveFolder的程序。 Activity在收到ACTION_CREATE_LIVE_FOLDER动作的Intent启动后,要通过setResult()调用的方式把活动目录的内容发回给它的调用者。返回的Intent的核心内容是需要设置一个Uri,表示活动目录要查询的ContentProvider的地址。 LiveFolders类中的另外几个数值表示创建LiveFolder后返回的附加参数。 EXTRA_LIVE_FOLDER_NAME:表示所建立的活动目录的名称(也就是出现在桌面的标签),为字符串“android.intent.extra.livefolder.NAME”,类型为String。 EXTRA_LIVE_FOLDER_ICON:表示活动目录在桌面显示的图标,为字符串“android.intent.extra.livefolder.ICON”,类型为Intent.ShortcutIconResource(作为Parcelable传递)。 EXTRA_LIVE_FOLDER_DISPLAY_MODE:表示活动目录的显示模式,为字符串“android.intent.extra.livefolder.DISPLAY_MODE”,类型为int ,具有两个数值可以使用:DISPLAY_MODE_GRID(网格)和DISPLAY_MODE_LIST(列表)。 EXTRA_LIVE_INTENT:表示活动目录中某个项目被点击后,启动内容的Intent,为字符串“android.intent.extra.livefolder.BASE_INTENT”,类型为Intent。 综合以上几个方面,LiveFolders被创建后,返回的Intent比较特殊,这个Intent实际上用于指向一个内容提供者,其中的Data域就是指向这个内容提供者的URI。它的额外参数定义了体现在桌面上的名称和图标,也体现了点击桌面图标后出现的对话框中的内容。 LiveFolder增加到桌面后的图标和选择LiveFolder的图标可以不同。在习惯上,为了区别桌面的Shotcut,LiveFolder的图标通常做成类似文件夹的形式。 2.LiveFolder的ContentProvider 在ContentProvider方面,需要在查询(query())的时候,支持几个特殊的域。这些域由LiveFolders类的几个常量定义,如下所示。 NAME:表示每个项目的名称,为字符串“name”,类型为String; DESCRIPTION:表示每个项目的描述,为字符串“description”,类型为String; INTENT:表示每个项目被选中后启动的内容,为字符串“intent”,类型为Intent; ICON_BITMAP:表示每个项目的图标,为字符串“icon_bitmap”,类型为Bitmap; ICON_PACKAGE:表示项目图标对应的应用程序包的名字,为字符串“icon_ package”,类型为String; ICON_RESOURCE:表示项目图标对应的资源名称,为字符串“icon_resource”,类型为Parcelable。 对于LiveFolder的ContentProvider的实现,以上的几个域只有NAME必须实现,其他是可选的。 LiveFolders实现了BaseColumns接口,因此其中也含有两个静态属性。 _ID:内容的id,为字符串“_count”,类型为INTEGER; _COUNT:内容的数目,为字符串“_id”,类型为INTEGER。 实现LiveFolder的ContentProvider也需要支持_ID和_COUNT两个域。 LiveFolder的实现 本节中的LiveFolder Sample程序实现了一个活动目录,增加后将在桌面出现一个图标。点击这个活动目录在桌面的图标,将在LiveFolder的列表框中显示一些内容。LiveFolder Sample的执行效果如图8-5所示。 图8-5中右图的列表项对话框共有8个项目,进一步点击每一个项目,还将出现浏览器显示空(blank)的网页。 LiveFolder Sample实现的AndroidMenifest.xml中定义的一个用于创建LiveFolder 的Activity和一个显示内容的ContentProvider,如下所示: <activity android:name="LiveFolderSample" android:icon="@drawable/app_icon" android:label="LiveFolder Sample"> <intent-filter> <action android:name="android.intent.action.CREATE_LIVE_FOLDER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <provider android:name="LiveFolderSampleProvider" android:authorities="livefoldersample"/> ▲图8-5 LiveFolder Sample(左:增加界面;中:LiveFolder的桌面图标;右:启动对话框) 这里声明的Activity支持“android.intent.action.CREATE_LIVE_FOLDER”动作,表示可以用它来创建活动目录,也就是可能在活动目录的增加列表中出现它这个项目。 public class LiveFolderSample extends Activity { private static final String URI = // ContentProvider的URI "content://" + "livefoldersample" + "/live_folders/virtual"; private static final Uri CONTENT_URI = Uri.parse(URI); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Intent intent = getIntent(); // 获得其中的Intent final String action = intent.getAction(); if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) { final Intent liveFolderIntent = new Intent(); // 返回结果中的Intent final Intent urlIntent = new Intent(Intent.ACTION_VIEW,Uri.parse("about://blank")); returnIntent.setData(CONTENT_URI); // Intent中的URI returnIntent.putExtra( // LiveFolder对话框的名称 LiveFolders.EXTRA_LIVE_FOLDER_NAME,"LiveFolderSample"); returnIntent.putExtra( // LiveFolder的图标 LiveFolders.EXTRA_LIVE_FOLDER_ICON,Intent.ShortcutIconResource. fromContext(this,R.drawable.app_icon)); returnIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE, LiveFolders.DISPLAY_MODE_LIST); returnIntent.putExtra( // LiveFolder中的每个内容Intent LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT,urlIntent); setResult(RESULT_OK, returnIntent); // 设置返回结果 } else { setResult(RESULT_CANCELED); } finish(); } } 在创建LiveFolder的过程中,涉及两个Intent。returnIntent是Activity返回的效果,在其中通过额外参数指定图标和活动目录的名称,其中主要的内容是指向ContentProvider的URI,并定义了其中的图标和名称。 返回内容returnIntent的一个特殊的域为urlIntent,也是一个Intent,它表示每一个项目被点击之后启动Activity的Intent。在这里将它定义为Intent.ACTION_VIEW 动作和以“about://blank”表示的Intent。当点击LiveFolder中的每一个项目的时候,将调用相应的程序(实际上是浏览器),对应的URI为“about://blank”再附加上每个内容的id。 这里的ContentProvider的实现内容如下所示: public class LiveFolderSampleProvider extends ContentProvider { private static final int VIRTUAL = 1; // 各个项目的id private static final int VIRTUAL_ID = 2; private static final int LIVE_FOLDER_SAMPLE = 3; public static final String AUTHORITY = "livefoldersample"; // URI private static final UriMatcher sUriMatcher; static { sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); // 建立匹配器 sUriMatcher.addURI(AUTHORITY, "virtual/", VIRTUAL); sUriMatcher.addURI(AUTHORITY, "virtual/#", VIRTUAL_ID); sUriMatcher.addURI(AUTHORITY, "live_folders/virtual", LIVE_FOLDER_SAMPLE); } // ...... 省略部分内容:query()方法的实现 @Override public String getType(Uri uri) { // 获取类型的实现 switch (sUriMatcher.match(uri)) { case VIRTUAL: case VIRTUAL_ID: return ""; case LIVE_FOLDER_SAMPLE: return ""; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public boolean onCreate() { return true; } @Override public Uri insert(Uri uri, ContentValues initialValues) { return null; // LiveFolder不要求实现insert() } @Override public int delete(Uri uri, String where, String[] whereArgs) { return 0; // LiveFolder不要求实现delete() } @Override public int update(Uri uri, ContentValues values, String where, String[] whereClause) { return 0; // LiveFolder不要求实现update() } } 对于为LiveFolder使用的ContentProvider,需要实现getType()方法,而其他方法不是必需的,如果要实现,可以在其他的地方对ContentProvider进行操作。 query()方法的实现是主要的内容,如下所示: @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) { switch (sUriMatcher.match(uri)) { // 查询操作的匹配 case VIRTUAL: // 不返回实际内容 case VIRTUAL_ID: return null; case LIVE_FOLDER_SAMPLE: return getLivefolder(); // 调用返回内容 default: throw new IllegalArgumentException("Unknown URI " + uri); } } private Cursor getLivefolder() { // 返回具体的内容 int i = 0; String[] columnNames = {LiveFolders._ID,LiveFolders.NAME}; // 2个必要的列 String[] temp = {"",""}; MatrixCursor c = new MatrixCursor(columnNames); for(i = 0 ;i < 8;i++){ // 循环返回8个项目 temp[0] = String.valueOf(i); // _ID的内容 temp[1] = LiveFolders.NAME + " = " + String.valueOf(i); // NAME的内容 c.addRow(temp); } return c; } 在查询返回的时候,实际上只有一个项有效,联系ContentProvider和LiveFolder创建者的是名称为“content://livefoldersample/live_folders/virtual”的URI。 查询返回具有两列的内容,其中第一列为_ID,第二列为NAME。前者表示每列的id,这是必须具有的,后者也就是反映在LiveFolder对话框中的每个项目显示的内容。 由于在这里没有为每个项目设置Intent域(LiveFolders.INTENT),因此每个项目在被选择之后将根据LiveFolder的创建者中设置的Intent附加上每个项目的id,作为启动的内容。例如,点击第2个项目将打开名称为“about://blank/1”的地址的空网页。 本文转自 wws5201985 51CTO博客,原文链接:http://blog.51cto.com/wws5201985/796642,如需转载请自行联系原作者

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

Android开发学习笔记:浅谈ToggleButton

ToggleButton(开关按钮)是Android系统中比较简单的一个组件,是一个具有选中和未选择状态双状态的按钮,并且需要为不同的状态设置不同的显示文本。 ToggleButton常用的XML属性 属性名称 描述 android:disabledAlpha 设置按钮在禁用时透明度。 android:textOff 未选中时按钮的文本 android:textOn 选中时按钮的文本 下面是具体的例子: 第一个例子是通过Toast显示ToggleButton不同的状态时的信息 MainActivity.java packagecom.android.togglebutton; importandroid.app.Activity; importandroid.os.Bundle; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Toast; importandroid.widget.ToggleButton; publicclassMainActivityextendsActivity{ //声明ToggleButton privateToggleButtontogglebutton; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); togglebutton=(ToggleButton)findViewById(R.id.togglebutton); togglebutton.setOnClickListener(newOnClickListener(){ publicvoidonClick(Viewv){ //当按钮第一次被点击时候响应的事件 if(togglebutton.isChecked()){ Toast.makeText(MainActivity.this,"你喜欢球类运动",Toast.LENGTH_SHORT).show(); } //当按钮再次被点击时候响应的事件 else{ Toast.makeText(MainActivity.this,"你不喜欢球类运动",Toast.LENGTH_SHORT).show(); } } }); } } 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" /> <ToggleButton android:id="@+id/togglebutton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textOn="喜欢" android:textOff="不喜欢" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">你喜不喜欢球类运动?</string> <stringname="app_name">测试ToggleButton</string> </resources> 效果图: 第二个例子通过图片的变化显示ToggleButton不同的状态时的图片 MainActivity.java packagecom.android.togglebutton; importandroid.app.Activity; importandroid.os.Bundle; importandroid.widget.CompoundButton; importandroid.widget.CompoundButton.OnCheckedChangeListener; importandroid.widget.ImageView; importandroid.widget.ToggleButton; publicclassMainActivityextendsActivity{ //声明ImageView,ToggleButton privateImageViewimageView; privateToggleButtontoggleButton; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //通过findViewById获得ImageView,ToggleButton imageView=(ImageView)findViewById(R.id.imageView); toggleButton=(ToggleButton)findViewById(R.id.toggleButton); toggleButton.setOnCheckedChangeListener(newOnCheckedChangeListener(){ publicvoidonCheckedChanged(CompoundButtonbuttonView,booleanisChecked){ toggleButton.setChecked(isChecked); //使用三目运算符来响应按钮变换的事件 imageView.setImageResource(isChecked?R.drawable.pic_on:R.drawable.pic_off); } }); } } 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"> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/pic_off" android:layout_gravity="center_horizontal" /> <ToggleButton android:id="@+id/toggleButton" android:layout_width="130dip" android:layout_height="wrap_content" android:textOn="开灯" android:textOff="关灯" android:layout_gravity="center_horizontal" /> </LinearLayout> 效果图: 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/655014

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

Android开发学习笔记:浅谈Toast

一.Toast的简介 Toast是Android中一种提供给用户简短信息的视图,该视图已浮于应用程序之上的形式呈现给用户。因为它并不获得焦点,即使用户正在输入什么也不会受到影响。它的目标是尽可能已不显眼的方式,使用户看到你提供的信息。显示的时间是有限制的,过一段时间后会自动消失,不过Toast本身可以控制显示时间的长短。 二.Toast的常用方法 int getDuration() 返回Toast视图显示持续的时间. int getGravity() 取得提示信息在屏幕上显示的位置. float getHorizontalMargin() 返回横向栏外空白 float getVerticalMargin() 返回纵向栏外空白. View getView() 返回View对象. int getXOffset() 返回相对于参照位置的横向偏移像素量。 int getYOffset() 返回相对于参照位置的纵向偏移像素量 staticToast makeText(Contextcontext, int resId, int duration) 生成一个从资源中取得的包含文本视图的标准Toast对象。 context使用的上下文。通常是你的Application或Activity对象 resId要使用的字符串资源ID,可以是已格式化文本。 duration该信息的存续期间。值为LENGTH_SHORT或LENGTH_LONG staticToast makeText(Contextcontext,CharSequencetext, int duration) 生成一个包含文本视图的标准Toast对象. void setDuration(int duration) 设置Toast视图显示持续的时间,LENGTH_LONG表示持续时间较长,LENGTH_SHORT表示持续时间较短 void setGravity(int gravity, int xOffset, int yOffset) 设置提示信息在屏幕上的显示位置.(自定义Toast的显示位置,例如toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0)可以把Toast定位在左上角。Toast提示的位置xOffset:大于0向右移,小于0向左移) void setMargin(float horizontalMargin, float verticalMargin) 设置视图的栏外空白. horizontalMargin容器的边缘与提示信息的横向空白(与容器宽度的比) verticalMargin容器的边缘与提示信息的纵向空白(与容器高度的比)。 void setText(int resId) 更新之前通过makeText()方法生成的Toast对象的文本内容.resId为Toast指定的新的字符串资源ID。 void setText(CharSequences) 更新之前通过makeText()方法生成的Toast对象的文本内容. s为Toast指定的新的文本 void setView(Viewview) 设置要显示的View.注意这个方法可以显示自定义的toast视图,可以包含图像,文字等等。是比较常用的方法 void show() 按照指定的存续期间显示提示信息 三.Toast的不同显示样式 效果图(有五种不同的Toast显示样式): main.xml <?xmlversion="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" > <Button android:id="@+id/btn_1" android:text="@string/btn1" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_2" android:text="@string/btn2" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_3" android:text="@string/btn3" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_4" android:text="@string/btn4" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_5" android:text="@string/btn5" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout> toast.xml <?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" android:background="#708090" > <ImageView android:id="@+id/img" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="带图片文字的Toast" /> </LinearLayout> strings.xml <?xmlversion="1.0"encoding="utf-8"?> <resources> <stringname="hello">HelloToast!</string> <stringname="app_name">ToastDemo</string> <stringname="btn1">系统默认的Toast</string> <stringname="btn2">自定义位置的Toast</string> <stringname="btn3">带只有图片的Toast</string> <stringname="btn4">有图有文字的Toast</string> <stringname="btn5">自定义布局的Toast</string> </resources> ToastDemoActivity.java packagecom.android.toast.activity; importandroid.app.Activity; importandroid.content.Context; importandroid.os.Bundle; importandroid.view.Gravity; importandroid.view.LayoutInflater; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.ImageView; importandroid.widget.LinearLayout; importandroid.widget.Toast; publicclassToastDemoActivityextendsActivity{ privateButtonbtn_1,btn_2,btn_3,btn_4,btn_5; privateToasttoast=null; @Override protectedvoidonCreate(BundlesavedInstanceState){ //TODOAuto-generatedmethodstub super.onCreate(savedInstanceState); setContentView(R.layout.main); btn_1=(Button)findViewById(R.id.btn_1); btn_2=(Button)findViewById(R.id.btn_2); btn_3=(Button)findViewById(R.id.btn_3); btn_4=(Button)findViewById(R.id.btn_4); btn_5=(Button)findViewById(R.id.btn_5); btn_1.setOnClickListener(newButtonClick()); btn_2.setOnClickListener(newButtonClick()); btn_3.setOnClickListener(newButtonClick()); btn_4.setOnClickListener(newButtonClick()); btn_5.setOnClickListener(newButtonClick()); } classButtonClickimplementsOnClickListener{ @Override publicvoidonClick(Viewv){ //TODOAuto-generatedmethodstub switch(v.getId()){ caseR.id.btn_1: toast.makeText(ToastDemoActivity.this,"默认的Toast显示",Toast.LENGTH_LONG).show(); break; caseR.id.btn_2: //getApplicationContext()得到程序当前的默认Context toast=Toast.makeText(getApplicationContext(),"自定义位置的Toast显示", Toast.LENGTH_LONG); //设置Toast的位置 toast.setGravity(Gravity.CENTER,toast.getXOffset()/2,toast.getYOffset()/2); toast.show(); break; caseR.id.btn_3: toast=Toast.makeText(getApplicationContext(),"只有图片的Toast显示", Toast.LENGTH_LONG); ImageViewimg=newImageView(ToastDemoActivity.this); img.setImageResource(R.drawable.android); toast.setView(img); toast.show(); break; caseR.id.btn_4: toast=Toast.makeText(getApplicationContext(),"有图有字的Toast",Toast.LENGTH_LONG); LinearLayoutlayout=(LinearLayout)toast.getView(); ImageViewimg1=newImageView(getApplicationContext()); img1.setImageResource(R.drawable.android); layout.addView(img1,0); toast.show(); break; caseR.id.btn_5: //将一个xml布局转换成一个view对象 LayoutInflaterinflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); Viewview=inflater.inflate(R.layout.toast,null); Toasttoast=newToast(getApplicationContext()); //在view中查找查找ImageView控件 ImageViewimage=(ImageView)view.findViewById(R.id.img); image.setImageResource(R.drawable.android); toast.setView(view); toast.show(); break; default: break; } } } } 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/638913

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

【移动开发】WIFI热点通信(一)

之前调查过Android中WIFI模块的使用,也写过两篇学习总结的文章(http://smallwoniu.blog.51cto.com/3911954/1334951),后来发现DEMO里面还是有许多不足之处,前段时间有不少人Q我,问到WIFI模块中的一些细节,小弟这里只能说声抱歉,因为当时的我也还没研究到那个层次呀。。。,后来毕业设计选题干脆直接选择了关于WIFI热点通信方面的题目,调查和整理了一些资料,进行了一段时间的学习算是弥补了自己的短板吧,主要还是希望自己能够更加全面的掌握这方面的知识。 废话不多说了!今天主要讲解WIFI热点通信的前期准备工作: 1.热点创建:创建指定名称的热点。 2.热点搜索:搜索附近可用热点,生成列表。 3.热点连接:在列表中点击指定名称的WIFI项,进行连接操作。 一.框架搭建 说明: 1.几个权限: 1 2 3 4 5 6 < uses-permission android:name = "android.permission.INTERNET" /> < uses-permission android:name = "android.permission.ACCESS_NETWORK_STATE" /> < uses-permission android:name = "android.permission.CHANGE_NETWORK_STATE" /> < uses-permission android:name = "android.permission.ACCESS_WIFI_STATE" /> < uses-permission android:name = "android.permission.CHANGE_WIFI_STATE" /> < uses-permission android:name = "android.permission.WAKE_LOCK" /> 2.相关类图: 二.模块讲解 接下来通过以下三个部分功能来逐一剖析,在此之前首先看一张最终的效果图加深以下印象: (由于本章讲解的部分是我的整个项目中的一部分,所以大家不用在意图片素材等其他细节) 2.1热点创建 点击WIFI管理界面中创建热点按钮,首先会检测当前WIFI是否可用,若可用则需将其关闭掉才能创建WIFI热点,因为手机热点把手机的接收GPRS或3G信号转化为WIFI信号再发出去,即你的手机就成了一个WIFI热点,所以共享和接收功能是不能同时进行的。之后就是创建指定名称的热点过程。热点创建时序图如下图所示。 几个核心方法: startApWifiHot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 /** *createahotwifi * *@paramwifiName */ public boolean startApWifiHot(StringwifiName){ Log.i(TAG, "intostartApWifiHot(StringwifiName)wifiName=" +wifiName); if (wifiManager.isWifiEnabled()){ wifiManager.setWifiEnabled( false ); } if (mWifiHotAdmin!= null ){ return mWifiHotAdmin.startWifiAp(wifiName); } Log.i(TAG, "outstartApWifiHot(StringwifiName)" ); return false ; } createWifiAp() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 /** *starthotpot *@paramwifiName *@return */ private boolean createWifiAp(StringwifiName){ Log.i(TAG, "intostartWifiAp()启动一个Wifi热点!" ); Methodmethod1= null ; boolean ret= false ; try { //setWifiApEnabledis@hide,soreflect method1=mWifiManager.getClass().getMethod( "setWifiApEnabled" , WifiConfiguration. class , boolean . class ); WifiConfigurationapConfig=createPassHotWifiConfig(wifiName,Global.PASSWORD); ret=(Boolean)method1.invoke(mWifiManager,apConfig, true ); } catch (IllegalArgumentExceptione){ e.printStackTrace(); Log.d(TAG, "stratWifiAp()IllegalArgumentExceptione" ); } Log.i(TAG, "outstartWifiAp()启动一个Wifi热点!" ); return ret; } 2.2热点搜索 点击WIFI管理界面中搜索热点按钮,同创建一样,首先需要检测WIFI热点是否关闭,将其关闭掉后才能打开WIFI搜索功能。在搜索完成后系统会发送WIFI状态变化广播来通知消息栏,这里通过自定义广播接收器接收了搜索成功消息,最后通过回调MainActivity中disPlayWifiScanResult()来显示WIFI列表。 几个核心方法: scanWifiHot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 /**scanwifihot**/ public void scanWifiHot(){ Log.i(TAG, "intowifiHotScan()" ); if (mWifiHotAdmin.isWifiApEnabled(wifiManager)){ mWifiHotAdmin.closeWifiAp(); } if (!wifiIsOpen()){ //WIFIisclosecurrently //listentothespecifiedSSIDwifistate registerWifiStateBroadcast( "" ); mWifiStateReceiver.setOperationsType(OperationsType.SCAN); //openwifi openWifi(); } else { //WIFIisopencurrently scanNearWifiHots(); } Log.i(TAG, "outwifiHotScan()" ); } scanNearWifiHots() 1 2 3 4 5 6 /**scannearwifi**/ private void scanNearWifiHots(){ registerWifiScanBroadcast(); //startscan wifiManager.startScan(); } 说明:这里的扫描实现过程是通过调用系统中WifiManager中扫描功能。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 /** *Requestascanforaccesspoints.Returnsimmediately.Theavailability *oftheresultsismadeknownlaterbymeansofanasynchronouseventsent *oncompletionofthescan. *@return{@codetrue}iftheoperationsucceeded,i.e.,thescanwasinitiated */ public boolean startScan(){ try { mService.startScan( false ); return true ; } catch (RemoteExceptione){ return false ; } } 2.3热点连接 在搜索完成之后,需要在WIFI列表中找到游戏的热点,点击连接过程会处理一系列逻辑:当前WIFI可用、是否已经连接、注册WIFI状态变化广播等,之后,开启独立线程进行热点匹配连接,热点连接时序图如图所示。 几个核心方法: connectToHotpot() 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 /** *connecttohotpot * *@paramssid *@paramwifiList *@parampassword */ public void connectToHotpot(Stringssid,List<ScanResult>wifiList,Stringpassword){ if (ssid== null ||password.equals( "" )||!ssid.equals(Global.HOTPOT_NAME)){ Log.d(TAG, "WIFIssidisnullor" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (ssid.equalsIgnoreCase(mSSID)&&isConnecting){ Log.d(TAG, "samessidisconnecting!" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (!checkCoonectHotIsEnable(ssid,wifiList)){ Log.d(TAG, "ssidisnotinthewifiList!" ); mWifiBroadCastOperator.disPlayWifiConnResult( false , null ); return ; } if (!wifiIsOpen()){ //listentossidwifi registerWifiStateBroadcast(ssid); mWifiStateReceiver.setOperationsType(OperationsType.CONNECT); //openwifi openWifi(); } else { //realconnecting enableNetwork(ssid,password); } } enableNetwork() 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 /** *connectwifihotreallybythread * *@paramssid *@parampassword */ private void enableNetwork( final Stringssid, final Stringpassword){ //deletemoreconnetedwifi deleteMoreCon(ssid); registerWifiConnectBroadCast(); new Thread( new Runnable(){ @Override public void run(){ WifiConfigurationconfig=WifiHotConfigAdmin.createWifiNoPassInfo(ssid,password); //ifconnectissuccessful isConnecting=connectHotSpot(config); mSSID=ssid; if (!isConnecting){ Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)isConnecting=" +isConnecting); return ; } } }).start(); } connectHotSpot() 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 /** *connectwifihotifsuccessful * *@paramwifiConfig *@return */ private boolean connectHotSpot(WifiConfigurationwifiConfig){ Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)" ); //theIDofthenewlycreatednetworkdescription int wcgID=wifiManager.addNetwork(wifiConfig); Log.i(TAG, "intoenableNetwork(WifiConfigurationwifiConfig)wcID=" +wcgID); if (wcgID< 0 ){ return false ; } boolean flag=wifiManager.enableNetwork(wcgID, true ); Log.i(TAG, "outenableNetwork(WifiConfigurationwifiConfig)" ); return flag; } 说明:连接热点的过程实质上就是获取热点配置信息,之后将其添加到自己的网络信息中同时使其可用。 至此,WIFI热点通信的前期工作已经完成,连接的手机端已在同一局域网内,若再有手机连接进来会自动为其分配该网段内的IP地址,接下来我们要做的就是在IP地址上实现数据的传输通信。在下一章中准备实现一个多人聊天室功能,希望能够帮助到大家! 源码下载:http://down.51cto.com/data/1812897 本文转自zhf651555765 51CTO博客,原文链接:http://blog.51cto.com/smallwoniu/1536126,如需转载请自行联系原作者

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

Android开发之adb无法连接

2017/11/14 21:20 Unable to run 'adb': null 21:20 'E:\AndroidSDK\platform-tools\adb.exe start-server' failed -- run manually if necessary 21:20 error: cannot open transport registration socketpair: Invalid argument 21:20 This application has requested the Runtime to terminate it in an unusual way. 21:20 Please contact the application's support team for more information. 21:20 could not read ok from ADB Server 21:20 * failed to start daemon * 21:20 error: cannot connect to daemon 2017/11/14 21:20 Unable to run 'adb': null 21:20 'E:\AndroidSDK\platform-tools\adb.exe start-server' failed -- run manually if necessary 21:20 error: cannot open transport registration socketpair: Invalid argument 21:20 This application has requested the Runtime to terminate it in an unusual way. 21:20 Please contact the application's support team for more information. 21:20 could not read ok from ADB Server 21:20 * failed to start daemon * 21:20 error: cannot connect to daemon adb无法连接,出现如上日志文件 解决方法: windows 10环境下关闭防火墙即可

资源下载

更多资源
Mario

Mario

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

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文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册