Android Intent与IntentFilter案例详解

1. 前言

       在Android中有四大组件,这些组件中有三个组件与Intent相关,可见Intent在Android整个生态中的地位高度。Intent是信息的载体,用它可以去请求组件做相应的操作,但是相对于这个功能,Intent本身的结构更值得我们去研究。

2. Intent与组件

       Intent促进了组件之间的交互,这对于开发者非常重要,而且它还能做为消息的载体,去指导组件做出相应的行为,也就是说Intent可以携带数据,传递给Activity/Service/BroadcastReceiver。

  • 启动Activity。Activity可以简单的理解为手机屏幕中的一个页面,你可以通过将Intent传入startActivity方法来启动一个Activity的实例,也就是一个页面,同时,Intent也可以携带数据,传递给新的Activity。如果想要获取新建的Activity执行结果,可以通过onActivityResult()方法去启动Activity。
  • 启动Service。Service是一个不呈现交互画面的后台执行操作组件,可以通过将Intent穿入startService()方法来启动一个Service来启动服务。
  • 传递广播BroadCast。广播是任何应用都可以接收到的消息,通过将Intent传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast()方法,可以将广播传递接收方。

3. Intent类型

在Android中,Intent分为两种类型,显式和隐式。

  • 显式Intent,可以通过类名来找到相应的组件,在应用中用显式Intent去启动一个组件,通常是因为我们知道这个组件(Activity或者Service)的名字。如下代码,我们知道具体的Activity的名字,要启动一个新的Activity,下面就是用的显示Intent。
Intent intent = new Intent(context,XXActivity.class);
startActivity(intent);
  • 隐式Intent,不指定具体的组件,但是它会声明将要执行的操作,从而匹配到相应的组件。最简单的Android中调用系统拨号页面准备打电话的操作,就是隐式Intent。
Intent intent = new Intent(Intent.ACTION_DIAL);
Uri data = Uri.parse("tel:" + "135xxxxxxxx");
intent.setData(data);
startActivity(intent);

使用显示Intent去启动Activity或者Service的时候,系统将会立即启动Intent对象中指定的组件。

       使用隐式Intent的时候,系统通过将Intent对象中的IntentFilter与组件在AndroidManifest.xml或者代码中动态声明的IntentFilter进行比较,从而找到要启动的相应组件。如果组件的IntentFilter与Intent中的IntentFilter正好匹配,系统就会启动该组件,并把Intent传递给它。如果有多个组件同时匹配到了,系统则会弹出一个选择框,让用户选择使用哪个应用去处理这个Intent,比如有时候点击一个网页链接,会弹出多个应用,让用户选择用哪个浏览器去打开该链接,就是这种情况。

       IntentFilter通常是定义在AndroidManifest.xml文件中,也可以动态设置,通常是用来声明组件想要接受哪种Intent。例如,你如果为一个Activity设置了IntentFilter,你就可以在应用内或者其他应用中,用特定的隐式Intent来启动这个Activity,如果没有为Activity设置IntentFilter,那么你就只能通过显示Intent来启动这个Activity。

注意,为了确保系统的稳定性,官方建议使用显示Intent来启动Service,同时也不要为Service设置IntentFilter,因为如果使用隐式Intent去启动Service,我们并不知道那些服务会响应Intent,而且由于服务大多是不可见的,我们也不知道那些服务被启动了,这是非常危险的。在Android 5.0(API 21)以后,如果使用隐式的Intent去调用bindService()方法,系统会抛出异常。

4. Intent的属性

       Intent作为消息的载体,系统根据它去决定启动哪个具体的组件同时将组件执行中需要的信息传递过去。Intent能够包含的属性有Component、Action、Data、Category、Extras、Flags,关于这些属性的更详细信息可查看这里

  • Component,要启动的组件名称。这个属性是可选的,但它是显式Intent的一个重要属性,设置了这个属性后,该Intent只能被传递给由Component定义的组件。隐式Intent是没有该属性的,系统是根据其他的信息(例如,Action、Data等)来判断该Intent应该传递给哪个组件。这个属性是目标的组件的具体名称(完全限定类名),例如,com.example.DemoActivity。该属性可以通过setComonentName()、setClass()、setClassName()或者Intent的构造函数来设置。
  • Action,表明执行操作的字符串。它会影响Intent的其余信息,比如Data、Extras。该属性可以通过setAction()方法或者Intent的构造函数来设置。用户可以自定义这个属性,也可以使用系统中已经有的Action值。下面列出启动Activity时候的一些通用Action属性。
    • ACTION_VIEW,当有一些信息需要展示出来,可以设置Intent的Action为这个值,并调用startActivity()方法
    • ACTION_SEND,当用户有一些信息需要分享到其他应用,可以设置Intent的Action为这个值,并调用startActivity()方法
    • ACTION_DIAL,拨打电话,可以设置Intent的Action为这个值,并调用startActivity()方法
    • ACTION_EDIT,编辑某些文件,可以设置Intent的Action为这个值,并调用startActivity()方法
  • Data,它是待操作数据的引用URI或者数据MIME类型的URI,它的值通常与Intent的Action有关联。比如,如果设置Action的值为ACTION_EDIT,那么Data的值就必须包含被编辑文档的URI。当我们创建Intent的时候,设置MIME类型非常重要。例如,一个可以显示图片的Activity可能不能播放音频,图片和音频的URI非常类似,如果我们设置了MIME类型,可以帮助系统找到最合适的组件接受Intent。有时候,MIME类型也可以从URI判断出来,例如当Data是一个包含content:字符串的URI时候,可以明确的知道,待处理的数据存在设备中,而且由ContentProvider控制。
    • 使用setData()方法设置数据引用的URI,使用setType()方法设置数据的MIME类型,使用setDataAndType()方法同时设置这两个属性。
    • 注意:如果想要设置两个的属性,直接用setDataAndType()方法,不要同时调用setData()和setType()方法,因为这两个方法设置的值会相互覆盖
    • public Intent setData(Uri data) {
      	mData = data;
      	mType = null;
      	return this;
      }
      public Intent setType(String type) {
          mData = null;
          mType = type;
          return this;
      }
      

  • Category,这个属性是对处理该Intent组件信息的补充。它是一个ArraySet类型的容器,所以可以向里面添加任意数量的补充信息,同时,Intent没有设置这个属性不会影响解析组件信息。可以通过addCategory()方法来设置该属性。下面列出一些常用的Category的值。
    • CATEGORY_BROWSABLE,设置Category为该值后,在网页上点击图片或链接时,系统会考虑将此目标Activity列入可选列表,供用户选择以打开图片或链接。
    • CATEGORY_LAUNCHER,应用启动的初始Activity,这个Activity会被添加到系统启动launcher当中。

以上列出的这些关于Intent的属性(Component、Action、Data、Category)可以帮助系统来确定具体的组件,但是有一些Intent的属性,不会影响到组件的确定。

  • Extras,以key-value键值对的形式来存储组件执行操作过程中需要的额外信息,可以调用putExtra()方法来设置该属性,这个方法接受两个参数,一个是key,一个是value。也可以通过实例化一个储存额外信息的Bundle对象,然后调用putExtras()方法将我们实例化的Bundle添加到Intent中。
  • Flags,这个属性可以指示系统如何启动一个Activity,以及启动之后如何处理。例如Activity属于哪一个task(参考Activity的四种启动方式)。

5. 显式Intent示例

       上文说到,显式Intent是用于启动某个特定的组件(Activity或者Service)的Intent,穿创建显式的Intent的时候需要设置组件名称(Component)属性,其他的属性都是可选属性。

// fileUrl是一个URL字符串,例如 "http://www.example.com/image.png"
Intent downloadIntent = new Intent(context, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

这里的Intent的构造函数传入了两个参数,context和组件名(Component),调用了startService()方法后,会在当前的应用中启动DownloadService这个服务。
显示Intent中设置的组件名(Component)需要在AndroidManifest.xml进行注册,所以它一般用来启动当前应用内的组件。

6. 隐式Intent示例

       隐式Intent比显示的Intent会复杂一些,它既可以启动当前应用内的组件,也可以启动当前应用外的组件。如果当前应用无法处理隐式Intent,但是其他应用中的组件可以处理,那么系统会弹框让用户选择启动哪个应用中的组件。

       例如,如果用户有内容想分享给其他应用,就创建一个Intent,将它的Action属性设置为ACTION_SEND,然后将要分享的内容设置到Extras属性中,然后调用startActivity()方法,用户就可以选择将内容分享到哪一个应用。

注意,如果没有任何应用能处理用户发送的隐形Intent,调用组件失败,应用可能会崩溃。调用resolveActivity()方法可以确认是否有Activity能够处理这个Intent,如果返回为非空,那么至少有一个组件能够处理这个Intent,调用startActivity()就很安全了;如果返回的是空(null),那么说明没有组件能够处理这个Intent,这个时候就不应该使用这个隐式的Intent了。

// 要将textMessage信息分享出去
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");

// 确认是否有组件能够处理这个隐式Intent
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

       调用startActivity()传入一个隐式Intent时候,系统会检查设备中所有的应用,确定哪些应用可以处理这个隐式的Intent(含有startActivity()操作并携带text/plain类型的Intent),如果只有一个应用可以处理这个Intent,那么直接唤起这个应用,并将Intent传给它;如果有多个应用可以处理这个Intent,那么系统会弹出一个选择框,让用户选择唤起哪个应用。

7. 强制唤起选择框

       上文说了,如果多个应用可以处理同一个隐式Intent,系统会弹出选择框,让用户选择唤起哪个应用,并设置该应用为默认的打开方式,以后就不会弹出选择框了。如果用户希望以后一直使用该用户处理这个隐式Intent(比如打开网页,用户通常会倾向于使用同一个web浏览器),那么十分方便。

       但是如果用户想每一次都用不同的应用去处理这个隐式的Intent的,就应该每次弹出选择框,用户可以在选择框中选择唤起的应用,但是无法设置默认的打开方式。例如,当用户想根据当前的位置将内容分享到不同的应用,所以每次都需要弹出选择框。

用户需要通过Intent.createChooser()创建一个Intent,然后调用startActivity()。

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...

// 分享的标题
String title = getResources().getString(R.string.chooser_title);
// 创建一个调用选择框的Intent
Intent chooser = Intent.createChooser(sendIntent, title);

// 确认是否有应用可以处理这个Intent
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

8. 接受隐式Intent

       想配置你的应用可以处理哪些隐式的Intent,需要在AndroidManifest.xml文件中使用<intent-filter>标签为组件设置一个或者多个过滤器。每一个过滤器基于Action、Data、Category来指定自身可以处理的Intent类型。如果隐式Intent的能够匹配到用户设置的其中一个过滤器,系统才能唤起这个应用相应的组件并将Intent传递给这个组件。

       组件应该为为一个它可以处理的操作单独设置一个处理器。例如,相册中的Activity可能有两个过滤器,一个过滤器对应浏览照片的操作,另一个过滤器对应编辑照片的操作。当这个Activity被启动的时候,根据Intent中携带的信息来决定执行哪种操作。

       每一个过滤器是在AndroidManifest.xml使用<intent-filter>标签来定义的,嵌套在组件标签中,例如<activity>、<service>标签。在<intent-filter>标签中,用户可以使用一下三个属性中的一个或者多个来指定可以接受的Intent。

  • <action>,在这个属性中,声明该组件可以执行的操作。该值必须是关于操作的一个字符串,并不是类常量
  • <data>,使用一个或者多个数据URI(scheme、host、port、path等等)和数据的MIME类型来指定接受的数据类型
  • <category>,声明接受的Intent类型

       Activity组件要接受隐式Intent,它必须有一个<category>属性为CATEGORY_DEFAULT的过滤器,因为startActivity()和startActivityForResult()方法处理Intent时候,默认的认为接受组件有一个<category>属性为CATEGORY_DEFAULT的过滤器。如果一个Activity组件不声明这样一个过滤器,它就接收不到隐式Intent。

例如,以下代码声明了一个Activity组件,这个组件可以处理action属性为ACTION_SEND,数据类型是文本(text/plain)的隐式Intent。

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

用户也可以创建一个包含多个<action>、<data>、<category>标签的过滤器,创建时候仅需要确定该组件能够处理过滤器定义的操作即可。

如果是根据<action>、<data>、<category>标签的组合来处理多个Intent,那么需要为这个组件声明多个过滤器。

系统会以这三个属性将隐式Intent与所有组件声明的过滤器进行对比,如果这三个属性全部能够匹配上,系统才有可能将这个隐式Intent传递给这个组件,因为如果多个应用的组件都能匹配上会弹出选择框,让用户选择一个应用去处理这个隐式Intent。

为了避免无意中启动了其他的Service,所以在应用内,建议一直使用显示的Intent去启动服务,这样就不必再AndroidManifest.xml文件中为Service声明过滤器了。

对于Activity的过滤器,必须在AndroidManifest.xml文件中声明,也可以不声明,直接使用显示Intent唤起Activity组件。

广播接收器的过滤器声明可以在AndroidManifest.xml文件中声明,也可以使用registerReceiver()方法动态注册,使用完毕后,使用unregisterReceiver()方法动态注销。

9. 过滤器声明示例

下面一些过滤器的声明能够帮助你更好的理解。

<activity android:name="MainActivity">
    <!-- 该Activity是该应用的启动入口页面,它会被储存在系统的launcher列表中 -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <!-- 该Activity能够处理ACTION_SEND行为且数据类型为text/plain的隐式Intent -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- 该Activity能够处理ACTION_SEND行为且数据类型是媒体内容的隐式Intent -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

第一个名为MainActivity的组件,是应用的启动入口页面,当用户点击应用图标,该Activity会被启动。

  • android.intent.action.MAIN,表示该Activity是应用的启动入口,且不需要任何Intent携带的数据。
  • android.intent.category.LAUNCHER,表示将该Activity的图标设为手机主屏幕上的应用图标,如果它没有图标,就用Application的图标。

第二个名为ShareActivity的组件,能够处理两种隐式Intent,可以接受文本和媒体内容的分享操作,也就是说如果一个隐式Intent能够匹配到任意一个过滤器都可以唤起该Activity。当然,也可以直接通过显示Intent指定启动它。

9. PendingIntent

PendingIntent是对Intent的一种封装。它主要作用在于,让外部的应用执行内部的Intent时候,就好像是在你的应用中还行一样。

通常在以下场景中会使用PendingIntent。

  • 当用户点击通知栏时候,才执行的Intent(系统的NotificationManager执行的Intent),详情参考这里
  • 当用户操作悬浮在主屏幕中的小工具,才执行的Intent(主屏幕应用执行的Intent),详情参考这里
  • 在未来某一个特定时间执行的Intent(系统的AlarmManager执行的Intent)

因为每一个Intent对象都是针对具体的组件类别(Activity/Service/BroadcastReceiver)进行实例化,因此在创建PendingIntent的时候,也要基于相同的因素去实例化,使用以下方法实例化PendingIntent。

  • PendingIntent.getActivity(),返回一个适用于Activity组件的PendingIntent
  • PendingIntent.getService(),返回一个适用于Service组件的PendingIntent
  • PendingIntent.getBroadcast(),返回一个适用于BroadcastReceiver的PendingIntent

当然官方还有一些其他获取PendingIntent对象的方法,不过内部也是使用上面三个方法来获取实例化对象的。

这三个方法都需要当前应用的context,需要封装的Intent,以及一个或者多个该如何使用该Intent的标志(例如,是否可以多次使用该Intent)。

关于Pending的具体使用也不再这里展开,需要了解具体使用的可以查看Notification中PendingIntent的使用悬浮工具栏中PendingIntent的使用

10. Intent匹配规则

       上文中提到了,当发送一个隐式Intent后,系统会将它与设备中的每一个组件的过滤器进行匹配,匹配属性有Action、Category、Data三个,需要这三个属性都匹配成功才能唤起相应的组件。

10.1 Action匹配规则

一个过滤器可以一个Action属性也可以声明多个Action属性。如下:

<intent-filter>
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.VIEW" />
    ...
</intent-filter>

隐式Intent中的Action属性,与组件中的某一个过滤器的Action能够匹配(如果一个过滤器声明了多个Action属性,只需要匹配其中一个就行),那么就算是匹配成功。

如果过滤器没有声明Action属性,那么只有没有设置Action属性的隐式Intent才能匹配成功。

10.2 Category匹配规则

一个过滤器可以不声明Category属性也可以声明多个Category属性,如下:

<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    ...
</intent-filter>

       隐式Intent中声明的Category必须全部能够与某一个过滤器中的Category匹配才算匹配成功。比如说一个Category属性设为CATEGORY_BROWSABLE的隐式Intent也可以通过上面的过滤器,也就是说,过滤器的Category属性内容必须是大于或者等于隐式Intent的Category属性时候,隐式Intent才能匹配成功。

如果一个隐式Intent没有设置Category属性,那么它可以通过任何一个过滤器的Category匹配。

10.3 Data匹配规则

一个过滤器可以不声明Data属性也可以声明多个Data属性,如下:

<intent-filter>
    <data android:mimeType="video/mpeg" android:scheme="http" ... />
    <data android:mimeType="audio/mpeg" android:scheme="http" ... />
    ...
</intent-filter>

每个Data属性都可以指定数据的URI结构和数据MIME类型。URI包括scheme、host、port 和path四个部分,host和port合起来也成authority(host:port)部分。

<scheme>://<host>:<port>/<path>

例如:

content://192.168.0.1:8080/folder/subfolder/etc

在这个URI中,scheme是content,host是192.168.0.1,port是8080,path是folder/subfolder/etc。我们平时使用的网络url就是这种格式。

在URI中,每个组成部分都是可选的,但是有线性的依赖关系

  • 如果没有scheme部分,那么host部分会被忽略
  • 如果没有host部分,那么port部分会被忽略
  • 如果host部分和port部分都没有,那么path部分会被忽略

当进行URI匹配时候,并不是比较全部,而是局部对比,以下是URI匹配规则。

  • 如果一个URI仅声明了scheme部分,那么所有拥有与其相同的scheme的URI都会通过匹配,其他部分不做匹配
  • 如果一个URI声明了scheme部分和authority部分,那么拥有与其相同scheme和authority的URI才能匹配成功,path部分不做匹配
  • 如果一个URI所有的部分都声明了,那么只有所有部分都相同的URI才能匹配成功

注意:path部分可以使用通配符(*),也就是path其中的一部分进行匹配。

Data匹配时候,MIME类型和URI两者都会进行匹配,匹配规则如下:

  • 如果过滤器未声明URI和MIME类型,则只有不含URI和MIME类型的隐形Intent才能匹配成功
  • 如果过滤器中声明URI但是未声明MIME类型(也不能从URI中分析出MIME类型),则只有URI与过滤器URI相同且不包含IME类型的隐式Intent才能匹配成功
  • 如果过滤器声明MIME类型但是未声明URI,只有包含相同MIME类型但是不包含URI的隐式Intent才能匹配成功
  • 如果过滤器声明了URI和MIME类型(既可以是直接设置,也可以是从URI分析出来),只有包含相同的URI和MIME类型的隐式Intent才能匹配成功

注意:进行匹配时候必须以过滤器为单位进行匹配,不能跨过滤器匹配。如果一个过滤器声明了多个Action、Category、Data,隐式Intent包含的Action、Category、Data都能在过滤器中匹配到相应的属性即可,也就是说过滤器中声明的属性是大于或者等于Intent中包含的属性,Intent才能匹配成功

11. 其他

       系统通过过滤器去匹配Intent,启动相应组件,在PackageManager类中提供了一系列的查询(queryIntentActivities()/queryIntentServices()/queryBroadcastReceivers())方法去查询可以处理某个Intent的组件,也提供了一系列的解析(resolveActivity()/resolveService())方法来确定最佳启动组件。这些方法在某些场景下是非常有用的,也可以帮助我们降低程序crash风险。

12. 思考

       上文中对Intent以及IntentFilter进行了详细的讲解,大多都是系统级别的处理过程。但是Intent作为一个官方已经封装好的信息携带者,我们可以用它来做很多事情。比如可以写自己的一套匹配规则,Intent仅仅作为数据携带者,通过它去传递一些信息,实现Fragment/Activity的页面跳转逻辑。关于Intent的使用,我相信还有更多的用处,需要用户一步一步的去探索。

到此这篇关于Android Intent与IntentFilter案例详解的文章就介绍到这了,更多相关Android Intent与IntentFilter内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Android BindService使用案例讲解

    最近学习了一下Android里面的Service的应用,在BindService部分小卡了一下,主要是开始没有彻底理解为什么要这么实现. BindService和Started Service都是Service,有什么地方不一样呢: 1. Started Service中使用StartService()方法来进行方法的调用,调用者和服务之间没有联系,即使调用者退出了,服务依然在进行[onCreate()-  >onStartCommand()->startService()->onDes

  • Android自定义软键盘的步骤记录

    目录 效果图 实现自定义软键盘 1.通过xml定义键盘 2.将xml文件与keyboardview绑定起来 3.处理点击事件onKey 附赠一些实用的效果处理 总结 效果图 还是咱们的老规矩,先放最终效果图

  • Android自定义view之3D正方体效果实例

    目录 前言 一.小提 二.将传感器改成事件分发机制 三.使用 四.源码 总结 前言 在之前写了一篇关于3D效果的文章,借助传感器展示,有小伙伴问可不可以改成手势滑动操作(事件分发),所以出一篇文章 传感器相关文章链接:Android 3D效果的实现 一.小提 相对于常见的自定义view而言,继承的GLSurfaceView只有两个构造函数.可以理解为没有提供获取自定义属性的方法. public TouchSurfaceView(Context context) { super(context);

  • Android自定义view之利用drawArc方法实现动态效果(思路详解)

    目录 前言 一.准备 1.测量 2.初始化画笔 3.自定义属性 二.关键方法介绍 drawArc 三.实现 1.思路 2.效果图 前言 前几天看了一位字节Android工程师的一篇博客,他实现的是歌词上下滚动的效果,实现的关键就是定义一个偏移量,然后根据情况去修改这个值,最后触发View的重绘来达到效果.于是今天根据这个思路来写一篇简单的文章.欢迎留言 一.准备 在这之前呢,还是得简单描述一下自定义view中的一些准备工作 1.测量 @Override protected void onSize

  • Android毕业设计备忘录APP

    目录 1.系统需求分析 1.2 系统需求 功能&说明 1.3 该项目涉及到的技术点 2.数据存储设计 2.1 SharedPrefenrences/SQLite存储介绍 SharedPrefenrences : SQLite存储 2.2数据表结构 3.具体编码及截图 3.1 主界面 3.2 各功能模块 4 总结 源码放到GitHub上了,大家可以看一下 https://github.com/become-better1/hh 1.系统需求分析 1.1 系统功能及框图 该项目实现了备忘录的创建,修

  • Android毕业设计记事本APP

    目录 前言 功能概述 系统设计 启动界面 引导界面 更改口令界面 主界面和编辑界面 1 建表 2 添加便签 3 在主界面显示便签 4 再次编辑该便签 5 主界面和编辑界面布局 前言 该设计是一款轻量级的便签工具,使用Android Studio开发,风格简练,可实现便签的添加.删除.修改.查看功能.为保证一定的安全性,设置了进入口令,类似于应用锁,用户可以修改口令.主要使用的技术有共享参数.数据库.SwipeRefreshLayout控件. 功能概述 用户打开应用后,启动页会判断用户是否第一次打

  • Android多返回栈技术

    目录 1.系统返回按钮的乐趣 2.Fragment 中的多返回栈 3.排除 Fragment 在技术上的障碍 4.Fragment 中值得期待的地方 4.使用 Navigation 将多返回栈适配到任意屏幕类型 5.在 Navigation 中启用多返回栈 5.保存状态,锁定用户 1.系统返回按钮的乐趣 无论您在使用 Android 全新的 手势导航 还是传统的导航栏,用户的 "返回" 操作是 Android 用户体验中关键的一环,把握好返回功能的设计可以使应用更加贴近整个生态系统.

  • 详解Android壁纸服务的启动过程

    壁纸基础 android中的壁纸分为动态壁纸和静态壁纸两种,两种类型的壁纸都以Service的类型运行在系统后台. 静态壁纸:仅以图片的形式进行展示对于静态壁纸,可以使用WallpaperManager中的getDrawable()等接口获取到当前的bitmap图像. 动态壁纸:显示的内容为动态的内容,同时可以对用户的操作做出响应对于动态壁纸的实时图像,是没办法通过android中原生的接口获取到,需要获取到动态壁纸的图像得自己修改源码. 壁纸实现时涉及的几个主要的类: WallpaperSer

  • Android ExpandableListView使用方法案例详解

    目录 一.前言 二.实现的功能 三.具体代码 1.主xml代码 2.父布局xml代码 3.子布局xml代码 4.主activity代码 5.adapter代码 一.前言   "好记性不如烂笔头",再次验证了这句话是真的很有道理啊,一个月前看了一下ExpandableListView的使用,今天再看居然忘了这个是干啥的了,今天就详细讲解一下ExpandableListView的使用方法,感觉对于二级条目显示功能都可以实现. 二.实现的功能 1.可实现二级列表条目显示功能,具体包括可自定义

  • Android Intent与IntentFilter案例详解

    1. 前言        在Android中有四大组件,这些组件中有三个组件与Intent相关,可见Intent在Android整个生态中的地位高度.Intent是信息的载体,用它可以去请求组件做相应的操作,但是相对于这个功能,Intent本身的结构更值得我们去研究. 2. Intent与组件        Intent促进了组件之间的交互,这对于开发者非常重要,而且它还能做为消息的载体,去指导组件做出相应的行为,也就是说Intent可以携带数据,传递给Activity/Service/Broa

  • Android 启动模式FLAG_ACTIVITY_CLEAR_TOP案例详解

    四种启动模式 standard: 只要被启动就会创建一个新的 singleTop: 栈顶复用(当被启动的Activity处于Task栈顶时,可以复用,直接调用onNewIntent方法) singleTask: 栈中复用(被启动的Activity已经处于栈中,会将上边的Activity清除出栈,调用onNewIntent) singleInstance 全局单实例(应用场景:地图,Activity初始化需要大量资源) Intent的标志位FLAG Intent.FLAG_ACTIVITY_SIN

  • Android Intent封装的实例详解

    Android Intent封装的实例详解 什么是Intent: Intent是协调应用间.组件之间的通讯和交互.通过Intent你可以启动Activity.Service.Broadcasts.更可以跨程序调用第三方组件.例如:启动拨打电话界面.音乐播放等. 组件     启动 Activity startActicity() Service startService(),bindService( ) Broadcasts sendBroadcast() 使用Intent: 栗子:在一个Act

  • Android开发之对话框案例详解(五种对话框)

    下面通过实例代码给大家分享5种android对话框,具体内容详情如下所示: 1 弹出普通对话框 --- 系统更新 2 自定义对话框-- 用户登录 3 时间选择对话框 -- 时间对话框 4 进度条对话框 -- 信息加载.. 5 popuWindow对话框 1 弹出普通对话框 --- 系统更新  //弹出普通对话框 public void showNormalDialog(View v) { AlertDialog.Builder builder = new Builder(this); //设置D

  • Android Kotlin使用SQLite案例详解

    Kotlin使用SQLite 首先确定我们的目标,SQLite只是一种工具,我们需要掌握就是增删改查就可以,我们真正需要动脑的还是项目中的业务逻辑.我这篇文章写得比较适合新手,没用过SQLite的同学. 前期准备工作 新建一个类MyDataBaseHelper继承自SQLiteOpenHelper,代码如下: class MyDatabaseHelper(var context: Context, name: String, version: Int) : SQLiteOpenHelper(co

  • Android BadTokenException异常解决案例详解

    目录 解决办法1 解决方法2 总结 线上出现了如上的 crash,第一解决反应是在 show dialog 之前做个 isFinish 和 isDestroyed 判断,当我翻开代码正要解决时,我惊了,原来已经做过了如上的判断检测,示例伪代码如下: public void showDialog(Activity activity){ new OkHttp().call(new Callback(){ void onSucess(Response resp){ if(activity!=null

  • Android 使用registerReceiver注册BroadcastReceiver案例详解

    android.context.ContextWrapper.registerReceiver public Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter) Register a BroadcastReceiver to be run in the main activity thread. The receiver will be called with any broadcast Intent

  • Android ActivityManager使用案例详解

    前言 Activity可以获取运行中的应用信息,可以获取到servcie,process,app,memory,Task信息等. 获取信息 ActivityManager.MemoryInfo MemoryInfo中重要的字段:availMem(系统可用内存),totalMem(总内存),threshold(低内存阈值,即低内存的临界线),lowMemory(是否为低内存状态) Debug.MemoryInfo Debug.MemoryInfo主要用于获取进程下的内存信息. ActivityMa

  • Android Location服务之LocationManager案例详解

    上次介绍了位置服务中的Geocoder,这次就来介绍一下LocationManager.LocationManager系统服务是位置服务的核心组件,它提供了一系列方法来处理与位置相关的问题,包括查询上一个已知位置.注册和注销来自某个LocationProvider的周期性的位置更新.注册和注销接近某个坐标时对一个已定义的Intent的触发等.今天我们就一起探讨一下LocationManager的简单应用. 在进入正题之前,朋友们需要了解与LocationManager相关的两个知识点: prov

随机推荐