《Android NFC开发实战详解》——6.4节Android NFC P2P开发进阶

简介:

本节书摘来自异步社区《Android NFC开发实战详解》一书中的第6章,第6.4节Android NFC P2P开发进阶,作者 赵波,更多章节内容可以访问云栖社区“异步社区”公众号查看

6.4 Android NFC P2P开发进阶
Android NFC开发实战详解
本节将介绍Android API 16+中引入的针对NFC P2P功能开发的新功能——文件传输进行介绍。该功能包括setBeamPushUrisCallback和setBeamPushUris两个方法。通过本节的介绍,大家可以结合NFC和蓝牙或WiFi很轻松的实现Android设备之间大数据(如图片、音乐等)的传输。

6.4.1 Beam实现文件传输的方法
Android4.1(Jelly Bean,Android API 16)新增了一种基于NFC和蓝牙(或WiFi)实现Android设备之间大数据传递的新方法,其中包含setBeamPushUrisCallback( )和setBeamPushUris( )两个方法。该方法比传统的蓝牙传输少了显示配对的过程,在你的应用无需考虑更多的其他工作同时还能发挥蓝牙传输的优势。

1.setBeamPushUrisCallback( )方法的原型
public void setBeamPushUrisCallback (NfcAdapter.CreateBeamUrisCallback callback, Activity activity)

其中,callback为通过Android Beam发送一个或多个动态生成的Uri(s)的回调接口;activity为当前调用该方法的activity,即push Uri(s)的Activity。

使用setBeamPushUrisCallback()方法时,应注意以下几点:

(1)该方法可以在Activity中任何位置调用(onDestroy()之前)。因为Uri只有Activity在前台状态(resume()状态)下才可用,所以Android的官方建议在OnCreate()中调用该方法。同时,由于该方法并不阻塞线程,因此可以在UI主线程中使用。

(2)使用该方法时,如果callback为null,则调用该方法的Activity的Uri Push功能将会disable。

(3)当同时使用该方法和setNdefPushMessage(NdefMessage, Activity, Activity...) 或setNdefPush MessageCallback(NfcAdapter.CreateNdefMessageCallback, Activity, Activity...)方法时,该方法具有较高优先级。

(4)关于该方法的使用,官方提供的使用范例如下(关于更详细的使用方法,读者可以参考本节后面的具体实例)。

protected void onCreate(Bundle savedInstanceState)
{
 super.onCreate(savedInstanceState);
 NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
 if (nfcAdapter == null)
  return; // NFC not available on this device
 nfcAdapter.setBeamPushUrisCallback(callback, this);
}

(5)如果用户的手机不支持蓝牙或WiFi,那么该方法将失效,使用该方法时则不会有任何反应。

(6)使用该方法需要在AndroidManifest.xml中添加NFC权限。

(7)在Android API 16+以上的系统中使用。

2.setBeamPushUris ( )方法的原型
public void setBeamPushUris (Uri[] uris, Activity activity):其中,uris为用于Android Beam的一个或多个Uri(s);activity为当前调用该方法的activity,即push Uri(s)的Activity。

使用setBeamPushUris()方法时,应注意以下几点:

(1)提供的每一个Uri中的Uri Scheme必须包含“file”或“content”。

(2)该方法可以在Activity中任何位置调用(onDestroy()之前)。因为Uri只有Activity在前台状态(resume()状态)下才可用,所以Android的官方建议在OnCreate()中调用该方法。同时,由于该方法并不阻塞线程,所以可以在UI主线程中使用。

(3)使用该方法时,如果Uri为null,则调用该方法的Activity的Uri Push功能将会disable。

(4)当同时使用该方法和setNdefPushMessage(NdefMessage, Activity, Activity...)或setNdefPush MessageCallback(NfcAdapter.CreateNdefMessageCallback, Activity, Activity...)方法时,该方法具有较高优先级。

(5)关于该方法的使用,官方提供的使用范例如下(关于更详细的使用方法,读者可以参考本节后面的具体实例)。

protected void onCreate(Bundle savedInstanceState)
{
 super.onCreate(savedInstanceState);
 NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
 if (nfcAdapter == null)
  return; // NFC not available on this device
 nfcAdapter.setBeamPushUris(new Uri[]
 { uri1, uri2 }, this);
 }
}

(6)如果用户的手机不支持蓝牙或WiFi,那么该方法将失效,使用该方法时则不会有任何反应。

(7)如果希望动态的提供Uri(s),那么可以使用上述的setBeamPushUrisCallback()方法。

(8)使用该方法需要在AndroidManifest.xml中添加NFC权限。

(9)在Android API 16+以上的系统中使用。

3.setBeamPushUrisCallback( ) 和setBeamPushUris( ) 的区别和选择
setBeamPushUrisCallback( )提供的是一个回调接口。当使用这个回调接口时,用户每Beam一次,该回调函数执行一次。如果待分享的Uri是动态的,会随着activity中的用户环境变化而变化,就可以使用该回调方法;反之,当待分享的Uri是静态的,是不会改变的,就可以使用setBeam PushUris( )方法提前定义好它们。总之,setBeamPushUris( )方法是在初始化Beam的同时立即提供Uri对象值,而setBeamPushUrisCallback( )回调方法在初始化Beam时并无需提供Uri对象值,而是在建立Beam连接时提供Uri对象值。

6.4.2 Beam文件传输实例1:setBeamPushUris
在Beam文件传输实例1中,本书对setBeamPushUris ( )方法实现Android Beam传输Uri功能进行了实例描述。由于Android Beam实现文件传输的方法中接收端可以由操作系统完成的,无需在App中处理,因此该实例中仅包括Uri发送端。Uri的Push部分主要包括两个步骤,分别为:

(1)在Activity中创建文件Uri。

(2)在需要的地方调用setBeamPushUris。

具体参见实例代码中对应的注释,详细代码如下:

1. package skyseraph.nfc_demo.p2p.beam.app;   //声明包

2. import skyseraph.android.util.LogUtil;  //导入相关类
3. ……//该处省略了导入相关类的代码
4. public class BeamFileDemo1 extends Activity implements OnClickListener
5. {
6.  private static final String Tag_ASSIST = "[BeamFileDemo1]-";
7.  private Context mContext = null;
8.  private boolean flagNFC = false;
9.  private boolean flagVersion = false;
10.  private static int mRequestCode = 1001;
11.  // NFC相关
12.  private NfcAdapter mNfcAdapter = null;
13. 
14.  @Override
15.  protected void onCreate(Bundle savedInstanceState)
16.  {
17.   // TODO Auto-generated method stub
18.   super.onCreate(savedInstanceState);
19.   mContext = this;
20.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into onCreate");
21.   flagNFC = checkNFCFunction();
22.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagNFC=" + flagNFC);
23.   if (flagNFC)
24.   {
25.    checkSystemVersion();
26.    LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagVersion=" + flagVersion);
27.    if(flagVersion)
28.    {
29.     // BNM步骤1: Create 文件Uri
30.     Intent i = new Intent(Intent.ACTION_GET_CONTENT);   
     //用户选择某种特殊数据并返回
31.     i.setType("image/*");   
     //查看类型,如果是其他类型,如视频则替换成 video/*,或 */*
32.     startActivityForResult(i, mRequestCode);
33.    }
34.   }
35.  }
36. 
37. 
38.  /*
39.   * (non-Javadoc)
40.   * 
41.   * @see android.app.Activity#onActivityResult(int, int,
42.   * android.content.Intent)
43.   */
44.  @Override
45.  protected void onActivityResult(int requestCode, int resultCode, Intent data)
46.  {
47.   // TODO Auto-generated method stub
48.   // super.onActivityResult(requestCode, resultCode, data);
49.   if (requestCode == mRequestCode && resultCode == RESULT_OK) 
50.   {
51.    Uri[] uriArray = new Uri[]
52.    { data.getData() };
53.    LogUtil.i(MyConstant.Tag, Tag_ASSIST + "uriArray=" + uriArray);
54.    
55.    // BNM步骤2:call setBeamPushUris anywhere your want
56.    mNfcAdapter.setBeamPushUris(uriArray, this);
57. 
58.    Button btn = new Button(this);
59.    btn.setText("Touch this to finish!");
60.    btn.setTextSize(30);
61.    btn.setOnClickListener(this);
62.    setContentView(btn);
63.   }
64.  }
65. 
66.  @Override
67.  public void onClick(View v)
68.  {
69.   finish();
70.  }
71. 
72.  /**
73.   * NFC Function Check By skyseraph 2013-2
74.   */
75.  private boolean checkNFCFunction()
76.  {
77.   // TODO Auto-generated method stub
78.   mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
79.   if (mNfcAdapter == null)
80.   {
81.    // mTextView.setText("NFC apdater is not available");
82.    Dialog dialog = null;
83.    CustomDialog.Builder customBuilder = new CustomDialog.Builder (mContext);
84.    customBuilder.setTitle(getString(R.string.inquire)).setMessage(getString(R.string.  
 nfc_notice2))
85.      .setIcon(R.drawable.dialog_icon2)
86.      .setNegativeButton(getString(R.string.no), new Dialog   
      Interface.OnClickListener()
87.      {
88.       public void onClick(DialogInterface dialog, int which)
89.       {
90.        dialog.dismiss();
91.        finish();
92.       }
93.      }).setPositiveButton(getString(R.string.yes), new Dialog   
      Interface.OnClickListener()
94.      {
95.       public void onClick(DialogInterface dialog, int which)
96.       {
97.        dialog.dismiss();
98.        finish();
99.       }
100.      });
101.    dialog = customBuilder.create();
102.    dialog.setCancelable(false);// back
103.    dialog.setCanceledOnTouchOutside(false);
104.    SetDialogWidth(dialog).show();
105.    return false;
106.   } else
107.   {
108.    if (!mNfcAdapter.isEnabled())
109.    {
110.     Dialog dialog = null;
111.     CustomDialog.Builder customBuilder = new CustomDialog.Builder   
      (mContext);
112.     customBuilder.setTitle(getString(R.string.inquire)).setMessage(getString(R.string.  
 nfc_notice3))
113.       .setIcon(R.drawable.dialog_icon2)
114.       .setNegativeButton(getString(R.string.no), new   
       DialogInterface.OnClickListener()
115.       {
116.         public void onClick(DialogInterface dialog, int which)  
117.        {
118.         dialog.dismiss();
119.         finish();
120.        }
121.       }).setPositiveButton(getString(R.string.yes), new   
       DialogInterface.OnClickListener()
122.       {  
123.         public void onClick(DialogInterface dialog, int which)
124.        {
125.         dialog.dismiss();
126.         Intent setnfc = new Intent(Settings.   
         ACTION_WIRELESS_SETTINGS);
127.         // Intent setnfc = new
128.         // Intent(Settings.ACTION_NFC_SETTINGS);
129.         startActivity(setnfc);
130.        }
131.       });
132.     dialog = customBuilder.create();
133.     dialog.setCancelable(false);// back
134.     dialog.setCanceledOnTouchOutside(false);
135.     SetDialogWidth(dialog).show();
136.     return false;
137.    } else if (!mNfcAdapter.isNdefPushEnabled())
138.    {
139.     Intent setnfc = new Intent(Settings.ACTION_NFCSHARING_SETTINGS);
140.     startActivity(setnfc);
141.     return false;
142.    } else
143.    {
144.     return true;
145.    }
146.   }
147.  }
148. 
149.  /**
150.   * @param dialog
151.   * @return
152.   */
153.  private Dialog SetDialogWidth(Dialog dialog)
154.  {
155.   DisplayMetrics dm = new DisplayMetrics();
156.   // 取得窗口属性
157.   getWindowManager().getDefaultDisplay().getMetrics(dm);
158.   // 窗口的宽度
159.   int screenWidth = dm.widthPixels;
160.   // 窗口高度
161.   int screenHeight = dm.heightPixels;
162.   WindowManager.LayoutParams params = dialog.getWindow().getAttributes();
163.   if (screenWidth > screenHeight)
164.   {
165.    params.width = (int) (((float) screenHeight) * 0.875);
166. 
167.   } else
168.   {
169.    params.width = (int) (((float) screenWidth) * 0.875);
170.   }
171.   dialog.getWindow().setAttributes(params);
172. 
173.   return dialog;
174.  }
175.  
176.  /**
177.   * check System Version()
178.   */
179.  private void checkSystemVersion()
180.  {
181.   // TODO Auto-generated method stub
182.   // if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
183. 
184.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "Product Model=" + android.os.     Build.MODEL + ", "+ android.os.Build.VERSION.SDK + ", " + android.os.Build. 
185.   VERSION.RELEASE);
186.   String systemModel;
187.   String releaseVersion;
188.   String sdkVersion;
189.   systemModel = android.os.Build.MODEL;
190.   sdkVersion = android.os.Build.VERSION.SDK;
191.   releaseVersion = android.os.Build.VERSION.RELEASE;
192.   if (Integer.parseInt(sdkVersion) > 15)
193.   {
194.    flagVersion = true;
195.   } else
196.   {
197.    flagVersion = false;
198.    Toast.makeText(mContext, "Your android system version is low to API-16", Toast.LENGTH_SHORT).show();
199.   }
200.  }
201. }

第21行为实现NFC功能的检测。在使用Android Beam功能前,需要确保设备支持NFC功能、NFC功能可用,且Android Beam功能是enable。具体可通过isEnabled() 和 isNdefPushEnabled()函数实现,参考代码第72~147行checkNFCFunction()函数。
第25行为实现系统版本的检测,因为setBeamPushUris ( )方法是在Android API 16+中才提供,所以此处加入了系统版本检测的代码。具体参考代码第176~200行checkSystemVersion()函数,该函数中主要通过android.os.Build.VERSION.SDK检测Android系统SDK API以及通过android.os.Build.VERSION.RELEASE检测Android系统版本。
第20~32行为BNM步骤1阶段,即准备Uri数据。代码通过Intent.ACTIONGET CONTENT进行过滤选择需要生产Uri的文件类型,本例中采用的是图片。
第38~64行中为onActivityResult()的处理,即用户选择了某个图片文件后进入到该函数中(根据第32行调用的startActivityForResult(i, mRequestCode)),具体包含了BNM步骤2阶段部分(即调用setBeamPushUris ( )方法)和UI操控部分(设置Button,用户触控结束该Activity)。
在AndroidManifest.xml中声明Activity,并添加NFC权限,其代码如下:

1. <uses-permission android:name="android.permission.NFC" />

2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3. <uses-feature
 android: name="android.hardware.nfc" 
 android:required="true" />
4. <activity
5.             android:name="skyseraph.nfc_demo.p2p.beam.app.BeamFileDemo1"
6.             android:label="NFC_Demo_BeamFile-1" >
7.             <intent-filter>
8.                 <action android:name="android.intent.action.MAIN" />
9. 
10.                 <category android:name="android.intent.category.skyseraph_nfc_demo" />
11.             </intent-filter>
12.         </activity>

第1行为APP添加NFC权限。
第2行为添加APP读取外部存储器权限。注意,在Android API 17+中已不再强调需要这个权限,但未来的平台版本可能会对想要从外部存储器上读取文件的应用程序要求这个权限。因此,为了确保兼容性,在它变成必须的要求之前,申请这个权限。
第3行为添加只有存在NFC功能的设备才能使用你的应用。
Beam文件传输实例1的具体效果如图6-13所示,其中,图6-13(a)为初次启动界面,即提示用户选择待分享的图片,用户选择完后,显示图6-13(b)所示的界面,此时,用户触碰界面结束当前分享界面。


d2369c9d563d2fd7a250d8df1737c9246b77de59

6.4.3 Beam文件传输实例2:setBeamPushUrisCallback
在Beam文件传输实例2中,本书对setBeamPushUrisCallback ( )方法实现Android Beam传输Uri功能进行了实例描述。同实例1,由于Android Beam实现文件传输的方法中接收端可以由操作系统完成的,无需在App中处理,因此实例2中也仅包括Uri发送端。Uri的Push部分主要包括三个步骤,分别为:

(1)在Activity中实现CreateBeamUrisCallback接口;

(2)在需要的地方调用setBeamPushUrisCallback;

(3)回调函数中实现Beam Data。

具体参见实例代码中对应的注释,详细代码如下:

1. package skyseraph.nfc_demo.p2p.beam.app;   //声明包

2. import skyseraph.android.util.LogUtil;  //导入相关类
3. ……//该处省略了导入相关类的代码
4. public class BeamFileDemo2 extends Activity implements CreateBeamUrisCallback,   
 OnClickListener
5. { // BNM步骤1:在你的Activity中实现CreateBeamUrisCallback接口(implements)
6.  private static final String Tag_ASSIST = "[BeamFileDemo2]-";
7.  private Context mContext = null;
8.  private boolean flagNFC = false;
9.  private static int mRequestCode = 1001;
10.  private Intent mIntent;
11.  // NFC相关
12.  private NfcAdapter mNfcAdapter = null;
13. 
14.  @Override
15.  protected void onCreate(Bundle savedInstanceState)
16.  {
17.   // TODO Auto-generated method stub
18.   super.onCreate(savedInstanceState);
19.   mContext = this;
20.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into onCreate");
21.   flagNFC = checkNFCFunction();
22.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "flagNFC=" + flagNFC);
23. 
24.   if (flagNFC)
25.   {
26.    Intent i = new Intent(Intent.ACTION_GET_CONTENT);   
    // 用户选择某种特殊数据并返回
27.    i.setType("image/*"); // 查看类型,如果是其他类型,如视频则替换成 video/*,或 */*
28.    startActivityForResult(i, mRequestCode);
29.   }
30.  }
31. 
32.  // BNM步骤3:回调函数中实现Beam Data。
33.  // 当发现有支持Beam的手机时,该回调接口会自动激活,你只需将你需要Beam的文件Uri准备好  
  // 并返回即可。
34.  // 本例中Uri为用户选择的图片为例。
35.  @Override
36.  public Uri[] createBeamUris(NfcEvent event)
37.  {
38.   // TODO Auto-generated method stub
39.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "into createBeamUris");
40.   Uri[] uriArray = new Uri[]
41.   { mIntent.getData() };
42.   LogUtil.i(MyConstant.Tag, Tag_ASSIST + "uriArray=" + uriArray);
43.   return uriArray;
44.  }
45. 
46.  /*
47.   * (non-Javadoc)
48.   * 
49.   * @see android.app.Activity#onActivityResult(int, int,
50.   * android.content.Intent)
51.   */
52.  @Override
53.  protected void onActivityResult(int requestCode, int resultCode, Intent data)
54.  {
55.   // TODO Auto-generated method stub
56.   // super.onActivityResult(requestCode, resultCode, data);
57.   if (requestCode == mRequestCode && resultCode == RESULT_OK)
58.   {
59.    mIntent = data;
60.    // BNM步骤2:call setBeamPushUrisCallback anywhere your want
61.    mNfcAdapter.setBeamPushUrisCallback(this, this);
62. 
63.    Button btn = new Button(this);
64.    btn.setText("Touch this to finish!");
65.    btn.setTextSize(30);
66.    btn.setOnClickListener(this);
67.    setContentView(btn);
68.   }
69.  }
70. 
71.  @Override
72.  public void onClick(View v)
73.  {
74.   finish();
75.  }
76. 
77.  /**
78.   * NFC Function Check By skyseraph 2013-2
79.   */
80.  private boolean checkNFCFunction()
81.  {
82.   // Beam文件传输实例1中的checkNFCFunction()函数,该处省略
83.  }
84. 
85.  /**
86.   * @param dialog
87.   * @return
88.   */
89.  private Dialog SetDialogWidth(Dialog dialog)
90.  {
91.   // Beam文件传输实例1中的SetDialogWidth ()函数,该处省略
92.  }
93. }

第4行为BNM步骤1阶段,即实现CreateBeamUrisCallback接口。实现该接口后,该Activity中需重载createBeamUris()函数。在该函数中返回需要Beam 的文件的Uri。
第21行为实现NFC功能的检测。在使用Android Beam功能前,需要确保设备支持NFC功能、NFC功能可用,且Android Beam功能是enable,具体通过isEnabled() 和 isNdefPushEnabled()函数实现,参考代码第77~83行checkNFCFunction()函数。
第26~28行为用户选择Uri数据,代码中通过Intent.ACTION_GET_CONTENT进行过滤选择需要生产Uri的文件类型,本例中采用的是图片。
第60~61行为BNM步骤2阶段,即调用setBeamPushUrisCallback(),调用该方法后Activity中会接收一个回调接口,一旦有发现其他设备的Beam数据,createBeamUris()就会自动调用。
第32~44行为BNM步骤3阶段,即回调接口createBeamUris(NfcEvent)中实现Beam Data,具体为将第26描述的用户选择的Uri数据获取并返回,Uri数组中的图片文件就会自动Beam to目标设备。
AndroidManifest.xml中声明Activity,并添加NFC权限,其代码如下:

1. <uses-permission android:name="android.permission.NFC" />

2. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
3. <uses-feature   
 android: name="android.hardware.nfc"   
 android:required="true" />
4. <activity
5.             android:name="skyseraph.nfc_demo.p2p.beam.app.BeamFileDemo2"
6.             android:label="NFC_Demo_BeamFile-2" >
7.             <intent-filter>
8.                 <action android:name="android.intent.action.MAIN" />
9. 
10.                 <category android:name="android.intent.category.skyseraph_nfc_demo" />
11.             </intent-filter>
12.         </activity>

第1行为APP添加NFC权限。
第2行为添加APP读取外部存储器权限。注意,虽然在Android 4.2.2 (API 17)中已不再强调需要这个权限,但未来的平台版本可能会对想要从外部存储器上读取文件的应用程序要求这个权限。因此,为了确保兼容性,在它变成必须的要求之前,申请这个权限。
第3行为添加只有存在NFC功能的设备才能使用应用。
Beam文件传输实例2的具体效果如图6-14所示。其中,图6-14(a)为初次启动界面,即提示用户选择待分享的图片。用户选择完后,显示图6-14(b)所示的界面。此时,用户触碰界面结束当前分享界面。


f40926aac0e608ea2936cb127b77134f6fa28e37
相关文章
|
4天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
27天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
14 0
|
1天前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。
|
18天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
21天前
|
监控 算法 Android开发
安卓应用开发:打造高效启动流程
【4月更文挑战第5天】 在移动应用的世界中,用户的第一印象至关重要。特别是对于安卓应用而言,启动时间是用户体验的关键指标之一。本文将深入探讨如何优化安卓应用的启动流程,从而减少启动时间,提升用户满意度。我们将从分析应用启动流程的各个阶段入手,提出一系列实用的技术策略,包括代码层面的优化、资源加载的管理以及异步初始化等,帮助开发者构建快速响应的安卓应用。
|
21天前
|
Java Android开发
Android开发之使用OpenGL实现翻书动画
本文讲述了如何使用OpenGL实现更平滑、逼真的电子书翻页动画,以解决传统贝塞尔曲线方法存在的卡顿和阴影问题。作者分享了一个改造后的外国代码示例,提供了从前往后和从后往前的翻页效果动图。文章附带了`GlTurnActivity`的Java代码片段,展示如何加载和显示书籍图片。完整工程代码可在作者的GitHub找到:https://github.com/aqi00/note/tree/master/ExmOpenGL。
22 1
Android开发之使用OpenGL实现翻书动画
|
21天前
|
Android开发 开发者
Android开发之OpenGL的画笔工具GL10
这篇文章简述了OpenGL通过GL10进行三维图形绘制,强调颜色取值范围为0.0到1.0,背景和画笔颜色设置方法;介绍了三维坐标系及与之相关的旋转、平移和缩放操作;最后探讨了坐标矩阵变换,包括设置绘图区域、调整镜头参数和改变观测方位。示例代码展示了如何使用这些方法创建简单的三维立方体。
17 1
Android开发之OpenGL的画笔工具GL10
|
物联网 API Android开发
Android官方开发文档Training系列课程中文版:通过NFC共享文件之发送文件到另一台设备
原文地址:http://android.xsoftlab.net/training/beam-files/index.html 导言 Android允许你通过Android Beam文件传输特性在两台设备之间传送大文件。
849 0
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
103 0
|
1月前
|
设计模式 人工智能 开发工具
安卓应用开发:构建未来移动体验
【2月更文挑战第17天】 随着智能手机的普及和移动互联网技术的不断进步,安卓应用开发已成为一个热门领域。本文将深入探讨安卓平台的应用开发流程、关键技术以及未来发展趋势。通过分析安卓系统的架构、开发工具和框架,本文旨在为开发者提供全面的技术指导,帮助他们构建高效、创新的移动应用,以满足不断变化的市场需求。
18 1