tag 标签: Android

相关帖子
相关博文
  • 热度 16
    2022-1-18 18:06
    865 次阅读|
    0 个评论
    Android之WebView用法
    除了 HTTP 通信与 Socket 通信两种主要的网络技术外,在 Android 中还提供了一种加载和显示网页的技术 —WebView 。这可以让我们去处理一些特殊的需求,比如像微信那样在应用程序里展示网页,或者说使用 WebView 来为 UI 界面布局。 WebView 的基本使用 WebView 的使用非常简单,新建一个项目 internet ,修改 activity _ main.xml 中的代码,加入一个 WebView 控件。 WebView 控件是一个新的控件,用于显示网页,为了可以在 Activity 中获取 WebView 而设置了 id ,代码如下 ∶
  • 热度 16
    2022-1-7 14:18
    1050 次阅读|
    0 个评论
    Android之Socket实例
    Socket(套接字)是对 TCP/IP 协议的封装和应用,根据底层封装协议的不同, Socket 的类型可以分为流套接字( streamsocket )和数据报套接字( datagramsocket )两种。流套接字将TCP作为端对端协议,提供了一个可信赖的字节流服务;数据报套接字使用 UDP 协议,提供数据打包发送服务,应用程序可以通过它发送最长 64KB 的信息。Socket 的通信模型图如1-1所示。 图1-1 Socket 的通信模型图 通过图1-1可以很容易地看出,使用Socket进行两个应用程序之间的通信时可以选择使用TCP还是UDP作为其底层协议。对比两种方式,就会发现它们各有优劣,TCP 首先连接接收方,然后发送数据,保证成功率,速度相对较慢(相比 HTTP 方式还是非常快的);UDP 把数据打包成数据包,然后直接发送对应的IP 地址,速度快,但是不保证成功率,并且数据大小有限。 一个功能齐全的 Socket,都要包含以下基本结构,其工作过程包含4个基本的步骤∶创建Socket,打开连接到 Socket 的输入/出流,按照一定的协议对 Socket进行读/写操作,关闭 Socket。 Java在java.net包中提供了 Socket 和 ServerSocket 两个类,分别用来表示双向连接的客户端和服务端,是Socket编程的核心类。构造方法很多,一般情况下使用下面两种∶ Socket client = new Socket("127.0.0.1 ",999); ServerSocket server = new ServerSocket(999); 其中,Socket 类用于实例化一个 Client,参数分别是要访问的IP 地址和端口号,这个端口号要与服务端一致。ServerSocket类用于实例化一个 Server,其中的参数用来设置端口这里的端口不能与"3306""80""8080"等常用端口号冲突。 下面以基于TCP的Socket为例来讲解如何使用Socket。 使用Java Socket创建一个服务端程序,运行在eclipse平台,并运行在PC上,然后在手机上编写客户端程序,在局域网内访问服务端。下面先编写服务端,代码如下: package socket; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class sockettest { public static void main(String 这里的代码很简单,单纯地使用ServerSocket建立服务,设置端口号为2226,然后每当有客户端访问时就返回一个“hello this is www.bigbirdic.com! ”。编辑完成服务端之后,我们在Android Studio中创建一个用于创建Socket客户端的类,代码如下: package com.rfstar.sockettest; import android.util.Log; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; public class SocketUtil { private String str; private Socket socket; private String ip; public SocketUtil(String str,String ip){ this.str=str; this.ip=ip; } public String sendMessage(){ String result=""; try{ socket=new Socket(); //ip为电脑所在的局域网网址 socket.connect(new InetSocketAddress(ip,2226),5000); OutputStream outputStream=socket.getOutputStream(); outputStream.write(str.getBytes()); outputStream.flush(); BufferedReader bfr=new BufferedReader(new InputStreamReader(socket.getInputStream())); String line=null; StringBuffer buffer=new StringBuffer(); while ((line=bfr.readLine())!=null) { buffer.append(line); } result=buffer.toString(); bfr.close(); outputStream.close(); socket.close(); }catch (SocketException e) { //连接超时,在UI界面显示消息 Log.i("socket",e.toString()); }catch (IOException e) { e.printStackTrace(); } return result; } } 在本类中,使用Socket连接服务器端,然后发送相关信息并接收服务端数据。代码并不难,下面就在MainActivity中使用此类。当然,使用它之前要先修改MainActivity的布局文件activity_main.xml,代码如下:
  • 热度 23
    2021-12-7 13:04
    918 次阅读|
    0 个评论
    Android之动态注册广播实例
    Android 内置了很多系统级别的广播,我们可以在应用序中通过监听这些广播来得到各 种系统 的状态信息,比如手机开机完成后会发出一条广播、电池的电最发生变化会发出一条广 播、 时间或时区发生改变也会发出一条广播等。 想 要实现广播的 接 收,就需要使用广播按收者。广播 接 收者可以自由地对自己感兴 趣 的 进 行注册。当有相 应 的广播发出时,广播 接 收者 就 能够收到该广播。 并 在内部处理相应的 逻辑 ,注册广 播 的方式一般有两种 , 在代码中注册和在 Androi dMan ifest . xml 中 注 册,其中的 前者 被 称 为动态注册,后者 被 称为静态注册。下面分别通过检测电话状态(动态注册)以及应用 开 机自动 ( 静 态注册 ) 两个实例来讲解系统广播的具体 用 法。 动态注册广播实例 这 里通 过一个检测电话状态的实例来讲解如何动态 注 册广 播 。在实例中如 果 想要 接 收到 这些 电话状态的广 播就 需要使用广播接收者。实现一个广播接收者只需要新建一个 继承自 BroadcastReceiver 类的子类并重写父类的 onR e ceive () 方法就行了。这样当有广播到来时 . onRceive () 方法 就会 得到执行,具体的业务逻编只需 在 onR e ceive () 方法中处理或可以了。 下面我们通过来看实例代码,新建一个 Activity 类,动态注册广播。当然这里需要注意权限问题,读取电话状态是一个危险权限,除了要在 AndroidManifest.xml 文件中加入如下代码: 还需要动态获取相关权限,下面是 MainActivity 的代码: package com.rfstar.broadcasttest; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private CallReceiver callReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getPermission(); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(callReceiver); } private void setCallReceiver() { callReceiver=new CallReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction("android.intent.action.PHONE_STATE"); filter.addAction("android.intent.action.NEW_OUTGOING_CALL"); registerReceiver(callReceiver,filter); } private void getPermission() { //判断版本号,在api23也就是6.0版本之前能直接获得权限 =23) { int checkCALLPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE); int checkOutCALLPermission=ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS); //判断是否具有权限 if(checkCALLPermission!= PackageManager.PERMISSION_GRANTED||checkOutCALLPermission!=PackageManager.PERMISSION_GRANTED) { //用以申请权限的方法,此时使用ActivityCompat类的该方法,以便于版本兼容 ActivityCompat.requestPermissions(this,new String permissions,int ==PackageManager.PERMISSION_GRANTED){ Toast.makeText(this,"获取权限成功",Toast.LENGTH_SHORT).show(); //获取权限成功,动态注册广播接收者 setCallReceiver(); }else{ Toast.makeText(this,"获取权限失败",Toast.LENGTH_SHORT).show(); } break; default: super.onRequestPermissionsResult(requestCode,permissions,grantResults); } } } 在 Activity 类中包括两部分内容 ∶ 一部分是动态获取权限,一部分是动态注册广播。这里只讲解动态注册广播。首先我们创建一个 Inten t Filt er 实例,并为其添加一个值为 android . intent . ac t ion.PHONE _ STATE 的 action 。接下来创建一个 CallReceiver 实例,然后调用 reg i sterRe cei ver () 方法进行注册,将 CallReceive r 的实例和 IntentFilter 的实例都传进去,这样 Ca l lRe c eiver 就会收到所有值为 android . intent . action.PHONE _ STATE 的广播,也就实现了监听电语状态的功能。一般情况下,动态注册的广播接收器一定要取消注册才行,取消注册通过在 onDestroy () 方法中通过调用 unregisterReceiver () 方法来实现。 新建一个继承自 BroadcastReceiver 类的 CallReceiver 类,用来获得用户拨打的电话号码以及接听、挂断等状态的变化,修改拨出的号码,加上一个 IP 拨号码,代码如下: package com.rfstar.broadcasttest; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.widget.Toast; public class CallReceiver extends BroadcastReceiver { boolean flag=false; @Override public void onReceive(Context context, Intent intent) { //判断是来电还是去电 if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){ //标识当前是拨出电话 flag=false; //获取当前号码 String phoneNumber=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); Toast.makeText(context,"电话已拨出,号码为:"+phoneNumber,Toast.LENGTH_LONG).show(); //将拨出的号码改为代码12159的号码 setResultData("12159"+phoneNumber); }else{ //此时监控来电时状态 //获取电话服务管理器 TelephonyManager TelephonyManager telephonyManager=(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE); switch (telephonyManager.getCallState()) { //电话处于响铃状态 case TelephonyManager.CALL_STATE_RINGING: //标识当前是来电 flag=true; //获取来电号码 String incomingPhoneNumber=intent.getStringExtra("incoming_number"); Toast.makeText(context,"来电号码:"+incomingPhoneNumber,Toast.LENGTH_LONG).show(); break; case TelephonyManager.CALL_STATE_OFFHOOK: if(flag){ Toast.makeText(context,"来电已被接通",Toast.LENGTH_LONG).show(); } break; case TelephonyManager.CALL_STATE_IDLE: if(flag){ Toast.makeText(context,"来电已被挂断",Toast.LENGTH_LONG).show(); } break; } } } } 在 onReceive () 方法中,首先通过 intent.getAction () 来判断是拨出电话还是外部来电。如果是拨出电话就获取拨出的号码,然后用 Toast 展示此号码,并使用 setResultData () 方法将此 号码 修改为带 IP 的号码进行拨号。如果是来电,就先通过 getSystemService () 方法获取 TelephonyManager 实例。这是一个系统服务类,专门用于管理通话。然后可以调用它的 g e t SystemService() 方法得到通话处于什么样状态,再根据不同的状态使用 Toast 展示不同的信息。 运行程序,按 home 键使当前程序进入后台,打开拨号界面,拨打电话,此时在界面上显示的号码就不再是拨出的号码,而是加上 "12159" 后的一个 I P 拨号号码。效果如 下 图所示 。 这里只展示了拨出电话时的效果。有关来电时的效果, 大家 可以使用上例自行测试验证 。 android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。
  • 热度 4
    2021-11-25 17:27
    1145 次阅读|
    1 个评论
    Android之IntentService的使用
    通过前面 的学习 , 大家 会发现我们在使用 Service 时总会创建一个线程来执行任务,而不是直接在 Service 中执行。这是因为 Service 中的程序仍然运行于主线程中,当执行一项耗时操作时,不新建一个线程的话很容易导致 Application Not Responding 错误。当需要与 UI 线程进行交互时,使用 Handler 机制来进行处理。 为了简化操作, Android 提供了 IntentService 类。 IntentService 是 Android 中提供的后台服务类,是 Service 自动实现多线程的子类。 IntentService 在 onCreate (函数中通过 HandlerThread 单独开启一个线程来处理所有 Intent 请求对象所对应的任务,这样以免请求处理阻塞主线程。执行完一个 Intent 请求对象所对应的工作之后,如果没有新的 Intent 请求到达,就自动停止 Service; 否则执行下一个 Intent 请求所对应的任务,直至最后执行完队列的所有命令,服务也随即停止并被销毁。所以如果使用 IntentService ,用户并不需要主动使用 stopService () 或者在 lntentService 中使用 stopSelf () 来停止。 lntentService 在处理请求时采用的也是 Handler 机制,它通过创建一个名叫 ServiceHandler 的内部 Handler 直接绑定到 HandlerThread 所对应的子线程。 ServiceHandler 把处理一个 intent 所对应的请求都封装到 onHandleIntent () 方法中,在开发时只需要直接重写 onHandleIntent () 方法,当开启服务之后系统会自动调用此方法来处理请求。 使用 IntentService 相当简单,只需继承 IntentService 类,实现 onHandleIntent () 方法并在其中处理相关请求的操作即可。下面通过一个实例来说明。 创建一个 Activity 类,并在布局文件中加入一个 Button 来开启服务 。
  • 热度 3
    2021-11-12 16:33
    1440 次阅读|
    0 个评论
    Android之AsyncTask使用实例
    AsyncTask 是 Android 提供的轻量级的异步类,可以直接继承 AsyncTask ,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现 UI 进度更新),最后反馈执行的结果给 UI 主线程。这个类的设计目的很明确,就是为了 " 执行一个较为耗时的异步任务(最多几秒钟),然后更新界面 " 。 这种需求本可以使用 Handler 和 Thread 来实现,但是在单个后台异步处理时显得代码过多、结构过于复杂,因此 Android 提供了 AsyncTask 类。但是在使用多个后台异步操作并需要进行 U I 变更时,使用 AsyncTask 类就变得复杂起来,使用 Handler 和 Thread 则更加合适。 另外,这里所说的轻量级只是代码上的轻量级,而非性能上的,使用 AsyncTask 会更加消耗性能 ∶ AymcTask 类有 4 个重要方法,这也是当一个异步任务被执行时要经历的 4 步,如表 1-1 所 示 。 表 1-1 AsyncTask 类的 4 个重要方法 方法 作用 onPreExecute() 在异步任务开始执行前在 U I 线程中执行,一般用来设置任务参数 dolnBackground() 最重要的方法,在子线程中执行(事实上,只有它在子线程中执行,其他方法都在 UI 线程中执行)。当 onPreExecute () 结束后,本方法立刻执行,用来进行后台的耗时计算 , 异步任务的参数会被传给它,执行完成的结果会被送给第四步。执行途中,它还可以调用 publishProgress () 方法来通知 U I 线程当前执行的进度 onProgressUpdate() 当 publishProgress () 被调用后,它在 UI 线程中执行,刷新任务进度,一般用来刷新进度条等 UI 部件 onPostExecute() 当后台的异步任务完成后,它会在 U I 线程中被调用,并获取异步任务执行完成的结 果 下面用一个实例来讲解如何使用 AsyncTask 类。创建一个继承自 AsyncTask 类的 MyAsyncTask 类,实现它的 4 个主要方法,并创建一个带参数的构造方法,用以介绍 Activi ty 类的 Content 和布局管理器。在 dolnBackground () 方法中模拟下载任务,并每隔 1 秒更新一次进度条。代码如下 ∶ package com.rfstar.asynctasktest; import android.app.ProgressDialog; import android.content.Context; import android.os.AsyncTask; import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; public class MyAsyncTask extends AsyncTask { private ProgressDialog progressDialog; private ViewGroup viewGroup; private Context context; public MyAsyncTask(Context context,ViewGroup viewGroup) { this.viewGroup=viewGroup; this.context=context; } @Override protected void onPreExecute() { super.onPreExecute(); //使用一个进度条对话框; progressDialog=new ProgressDialog(context); progressDialog.setTitle("正在下载中,请稍后......"); //设置ProgressDialog样式为圆圈的形式 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.show(); } @Override protected String doInBackground(Object ; int flag=0; while (flag<100){ flag+=20; //跟新进度,将回调onProgressUpdate()方法 publishProgress(flag); try{ Thread.sleep(1000); }catch (Exception e){ } } return address+"从这个下载地址下载了一本小说,欢迎阅读。"; } @Override protected void onProgressUpdate(Object ); } @Override protected void onPostExecute(Object o){ super.onPostExecute(o); //在布局中加入一个TextView TextView textView=new TextView(context); textView.setText((String)o); viewGroup.addView(textView); //关闭进度条 progressDialog.dismiss(); } } 同时建立一个 Activity ,在布局文件中加入一个 Button, 当点击 Button 时,实例化 MyAsyncTask 类并调用 excute() 方法。布局文件代码如下:
相关资源