Android官方开发指南翻译(未整理)

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
基础
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
一旦一个android应用程序被安装,则它只存在于属于它自己的安全沙箱里:
=》android操作系统是基于多用户的linux操作系统,所以每个应用程序属于不同的用户;
=》默认情况下,系统为每个应用程序分配一个唯一的用户id(只有系统知道该ID,对于应用程序是透明的),系统将该应用程序的所有权限分配给该用户;
=》每个进程都在自己的虚拟机中运行,所以应用程序之间是相互隔离的。
=》默认情况下,每个应用程序运行在它自己的linux进程中。当应用程序的某个组件需要被执行的时候,android开启一个进程;当应用程序不再被使用,或者系统需要为其他应用程序提供运行空间时,该进程将关闭。
这样,android系统实现了最小权限原则:默认情况下,每个应用程序只能访问与自身工作相关联的组件。这样就创建了一个非常安全的环境,每个应用程序不能在没有权限的情况下访问系统的其他资源;
应用程序间共享数据,或访问系统服务的方式:
=》为部同的应用程序分配相同的用户id
=》每个应用程序都能申请访问设备数据,如联系人,短彩信,sd卡,相机,蓝牙等等。应用程序申请的权限必须只在安装时被授予;
四种应用程序组件:
=》Activities:一个activity为用户提供一个用户界面接口。例如,一个电子邮件应用程序可能有一个展示新邮件列表的activity,一个新建邮件的activity,和一个阅读电子邮件的activity。虽然这些activity给了用户一个连贯的用户体验,但是每个activity之间是相互独立的。因此,不同的应用程序可以启动任何一个activity(在电子邮件应用程序运行的情况下)。比如一个照相机应用程序可以启动电子邮件应用程序中的“新建邮件activity”,新建一个电子邮件,和朋友分享相片。
一个activity可以通过继承Activity类实现。
=》Services:Services是一个后台运行的组件,完成一些运行时间较长或者需要远程调用的进程。service不提供用户接口,例如,一个service可以在当用户正在使用其他应用程序时后台播放音乐,或者在不需要用户交互的时候抓取网络数据。activity可以开启service,运行service以及绑定service进行交互操作。
一个service可以通过继承Service类实现。
=》Content Providers:一个content provider管理应用程序的共享设置。你可以将数据存储在文件系统,SQLite数据库,web,或者其他持久化设备中。通过content provider,其他应用程序能查询甚至修改这些数据(如果content provider 允许)。例如,android系统提供了联系人信息的content provider。这样,任何拥有合适权限的应用程序都能查询这个content provider提供的功能去阅读、修改特定联系人的信息。
content provider对于读写私有数据也是非常有用的。例如,Note Pad示例程序使用content provider去保存日记。
一个content provider可以通过继承ContentProvider类实现。
=》Broadcast receivers:一个broadcast receiver是一个能在系统范围内接受通知的组件。一些broadcast起源于系统,例如,一个broadcast通知显示屏已经关闭,电池电量不足,或者拍照成功.应用程序也能初始化broadcast,例如,让其他应用程序知道某些数据已经成功下载到设备上,可以正常使用.虽然broadcast receiver不能展示用户接口,但是它们可以创建一个状态bar notification去告知用户有一个通知事件发生了。更通用的是,一个broadcast receiver恰恰就像一个其他组件的关口一样,确定将要做一些非常少量的工作。例如,它可以初始化一个service去完成仪式基于事件的工作。
一个broadcast receiver可以通过继承BroadcastReceiver来实现,每个broadcast将作为一个intent对象传输。


Android系统中有个独特的功能就是任何应用程序都能开始其他任何应用程序的组件。例如,如果你想让用户使用照相机拍照,而这个功能完全可以由其他应用程序完成,你的应用程序只需要使用就可以了,而不需要你自己去开发实现拍照的activity功能。或许,你会想到从照相机应用程序中并入,甚至连接相关代码。相反,你可以简单的启动照相机应用程序中的照相activity。当照相完成之后,相片返回到你的应用程序中供你使用。对于用户来说,照相功能就好像你自己应用程序的一部分。


当系统启动一个组件时,系统会为该应用程序创建一个进程(如果该应用还未运行),并且初始化这个组件需要的类。例如,你的应用程序开启一个照相机应用程序中的activity拍照,那么那个activity运行在照相机应用程序的进程之中,而不是你自己应用程序的进程里。因而,不像其他系统中的应用程序,android应用程序没有一个程序入口(例如main函数)。


业务系统使用文件权限在独立进程中运行应用程序,这样可以约束访问其他应用程序,你的应用程序不能直接激活其他应用程序的组件。但是,android系统可以激活其他应用程序的组件,你必须传递消息告诉系统你要启动一个特定组件的意图。然后系统将为你激活该组件。


激活组件:
=》在四个组件中,三个组件(Activities, Broadcast receivers, services)会被一个叫做intent的异步消息激活。
Intents在运行时绑定相互之间的单个组件(你可以认为他们是一个从其他组件发出请求动作的信使),即使该组件不属于你的应用程序。


激活Activity:通过传递一个Intent给startActivity()或者startActivityForResult(),当你想要这个activity返回结果时使用。
激活service:通过传递一个Intent给startService(),或者通过传递一个Intent给bindService()绑定服务。
激活BroadcastReceiver:通过传递一个Intent给sendBroadcast,sendOrderedBroadcast(),或者sendStickyBroadcast()
激活Content Providers:你能通过一个content provider调用ContentResolver的query()方法完成。


Manifest.xml文件
=>android系统能启动一个应用组件之前,系统必须知道这个组件是否存在。系统通过解析应用程序的AndroidManifest.xml读取应用程序的组件,所以你必须在AndroidManifest.xml中声明你的程序里的所有组件,而且AndroidManifest.xml必须在应用程序的根目录下。
AndroidManifest.xml除了声明组件以外,它还有其他很多功能,比如:
<1>确定应用程序需要的系统权限,比如访问internet、读取联系人信息权限;
<2>基于应用程序使用的最小api,声明系统需要的最小api level;
<3>声明需要或使用的软、硬件功能,比如照相机、蓝牙或者多点触控;
<4>需要连接的api库,不如谷歌地图库
<5>等等


=>声明组件:AndroidManifest.xml的主要功能是通知系统该应用程序的所有组件。比如一个AndroidManifest.xml能如下声明一个activity:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
    <application android:icon="@drawable/app_icon.png" ... >
        <activity android:name="com.example.project.ExampleActivity"
                  android:label="@string/example_label" ... >
        </activity>
        ...
    </application>
</manifest>


在AndroidManifest.xml中声明四大组件:
<activity>
<service>
<provider>
<receiver>
这里,activities,services,providers相关组件必须在这里声明。系统将永远不会执行AndroidManifest.xml中未声明的组件。但是,broadcast receiver除外。broadcast receiver不仅可以在AndroidManifest.xml中声明,还可以在代码用动态创建,并且通过调用registerReceiver()方法注册到系统中。


声明组件性能:正如前面所讲,在激活组件中,你可以使用一个Intent去启动一个activities,services,以及broadcast receiver。你也可以在Intent中显示的为目标组件命名(使用组件类名)。但是intents真正是作用隐藏在intents actions里。有了intent actions, 你狠简单就的描述你想要处理的action类型(或者,你完成这个action需要的数据),并且允许系统找到设备上的这个组件从而执行这个action并且启动它。如果有过个组件能处理同一intent里的action,那么由用户选择使用哪个组件。


系统判定响应一个intent的方法是通过把接收到的intent与设备上的其他应用程序的manifest文件中的intent filter作比较。
当你在应用程序的manifest文件中声明一个组件时,你可以包含多个intent 过滤器去响应其他应用程序的intents。你可以使用一个<intent-filter>元素作为主键声明的子元素来声明你的intent filter.
例如,一个新增电子邮件的email应用程序的activity可以声明一个intent filter去响应"send"意图。你就可以在你的应用程序中写一个activity,该activity中创建一个"send"action(ACTION_SEND)的intent,当你调用startActivity()时,系统就会找到email应用程序的"send"activity,并启动它。


声明应用程序的需求:
比如,如果你的应用程序需要一个摄像机,并且需要android2.1的api,你应该在manifest文件中声明这些需求。这样,如果设备没有摄像机,并且设备使用的android api小于2.1,那么该设备将不能从android市场安装你的应用程序。


但是,你也可以不通过提出requires去申请摄像机。这样,你的应用程序必须在运行时检查设备是否有摄像机,并且在没有的情况下禁用与摄像机相关的功能。
在你设计和开发你的应用程序时,你需要考虑一些重要的设备特征:
<1>屏幕大小和分辨率:为了给屏幕进行分类,android为每种设备定义了两种特征:屏幕大小(屏幕的物理尺寸)和屏幕分辨率(屏幕上像素的物理密度)。为了简化不同类型的屏幕设置,android系统将他们分为不同组,以便更简单。
屏幕尺寸:small, normal, large, extra large.
屏幕分辨率:low density, medium density, high density, extra high density.
默认情况下,你的应用程序与屏幕大小和分辨率是一致的。因为android系统为你的ui布局和图像资源做了适当的调整。但是,对于某一个特定的屏幕和分辨率,你应该创建专门的布局和,使用不同的布局资源。特别地,需要通过在你的manifest文件中用<supports-screens>声明你的应用程序支持的屏幕大小。
输入设置:一些设备提供了不同类型的用户输入,比如硬件键盘等。如果你的应用程序需要一个特别的输入硬件,你应该在manifest文件中用<uses-configuration>声明。但是,这种需要特定输入配置的应用程序比较稀少。
设备特征:有许多硬件和软件特征没有在android系统中支持的,比如摄像机,光线传感器,蓝牙,特定版本的OpenGL等等。
平台版本:不同的android设备经常运行在不同的android平台上,比如android1.6或者android2.3。每个版本经常包含前一版本没有的额外功能。需要在<uses-sdk>元素中声明版本信息。




++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Activity
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1、创建一个activity
<1>笔记继承自Activity类,并且实现相关的回调函数,比如createed,stopped,resumed,destroyed.必须实现的两个重要的回调方法是:onCreate()和onPause();
2、实现用户接口。最普遍的方式是定义布局的xml文件,该文件保存于你应该程序的资源文件夹内。这样可以与代码分离,便于维护。使用布局文件的方法是,传递ViewGroup给setContentView();
3、在manifest中声明activity.
4、使用intent filters.一个<activity>元素通过<intent-filter>指定多个不同的intent filters
如果你想让你的应用程序自己使用而不允许其他应用程序激活,那么你不需要任何其他intentfilters。只有一个activity有"main"action和"launcher"类型。
5、启动一个activity:调用startActivity()或者调用startActivityForResult(),并且用onActivityResult()方法接收;
6、关闭一个activity:你可以通过调用一个activity的finish()方法,或者调用finishActivity();


两个非常重要的方法:onCreate()和onPause():需要在onCreate()方法中初始化相关数据和组件。最重要的是,你需要调用setContentView()方法设置布局和控件等等;当用户离开你的应用程序时需要调用onPause()方法,所以需要在该方法中作一些适当的善后工作。


启动一个无需返回值的activity:
方法一:
Intent intent = new Intent(this, SignInActivity.class);
startActivity(intent);
方法二:
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
startActivity(intent);
启动一个需要返回结果的activity:
方法:注意回调方法onActivityResult()
Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
    startActivityForResult(intent, PICK_CONTACT_REQUEST);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
    if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) {
        // Perform a query to the contact's content provider for the contact's name
        Cursor cursor = getContentResolver().query(data.getData(),
        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
        if (cursor.moveToFirst()) { // True if the cursor is not empty
            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
            String name = cursor.getString(columnIndex);
            // Do something with the selected contact's name...
        }
    }
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
service
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Service,一种应用程序组件,它能在后台,即不提供用户接口,完成耗时的操作。其他应用程序组件能启动一个service,即使用户跳转到其他应用程序,它也能在后台运行。另外,一个组件也可以绑定一个service,以便与之交互,甚至完成进程间通信。例如,一个service可以在后台处理网络数据交换,播放音乐,完成文件输入、输出,与content provider进行交互。
建立service的两种方式:
1、启动型Service:应用程序组件通过调用startService()启动一个service。一旦启动,即使启动它的组件被销毁,service也能在后台持续运行。通常,一个service只完成单个操作,并且不返回结果给调用者。例如,它可以通过网络上传或下载一个文件。当操作完成之后,service会自动停止。
2、绑定型Service:一个应用程序可以通过调用bindService()绑定一个service。被绑定的service提供一个客户端-服务器接口,组件与service通过该接口进行交互,发送请求,获得结果,甚至通过IPC访问其他进程。有且只有绑定service的组件在运行,这个service将保持运行状态。多个组件可以绑定同一个service,但每个组件只能绑定一次,但是绑定某个service的组件都取消绑定之后,这个service将销毁。
虽然该文档分开讨论了使用service的两种方式,但是你的service可以同时运行两种方式——一个已经在后台运行的service也允许被绑定。有个简单的方式是实现两个回调方法:实现onStartCOmmand()允许组件启动该service;实现onBind()方法允许组件绑定。
不管你的应用程序启动、绑定,即使两者都使用某个service,任何应用程序组件能用相同的方式操作这个service(即使是其他应用程序组件)。但是,你可以在manifest文件中声明一个service为私有,以便阻塞其他应用程序访问。
警告:一个service在宿主线程的主线程中运行——service不会创建它自己的线程,也不会在不同的进程中运行。也就是说,如果你的service将要做一些频繁使用cpu或阻塞操作(比如mp3回放或者联网操作),你应该在这个service中创建一个新线程去做这些工作。通过使用一个单独的线程,你将减少应用程序无效应的的风险,同时应用程序主线程可以通过activity保持与用户的交互操作。
基本内容:创建一个service,你必须创建一个Service的子类。在你的实现中,你需要重写service生命周期中的一些关键回调方法,同时在合适情况下,应该重写组件绑定到service的方法。
你应该重写的两种重要的回调方法:
1、onStartCommand():当其他组件,比如activity,通过调用startService()方法请求启动一个service时,系统将调用onStartCommand()。一旦这个方法开始执行,这个services就启动了,并且在后台持续运行。如果你实现了这个方法,你就应该在service工作完成之后通过调用stopSelf()或者stopService()停止该service。(如果只想为service提供绑定,那么久不需要实现这个方法onStartCommand()。)
2、onBind():当其他组件通过bindService()绑定一个service时,系统将调用onBind()方法。在你重写这个方法时,你必须提供一个接口,以便调用者可以通过IBinder与这个service交流。你必须实现这个方法,但是如果你不想被绑定,那么你可以返回null;
3、onCreate():当service第一次被创建时,系统将调用该方法去完成“安装一次”操作。但是,如果service已经处在运行状态,这个方法将不会被调用。
4、onDestroy():当service不再使用或者正在被销毁时,系统将调用该方法。你的service应该重写这个方法以便释放资源,如线程,已经注册的监听器,接收器等。该方法将是系统对service的最后一次调用。
如果一个组件通过调用startService()启动service(系统自动调用onStartCommand()),要么service自己调用stopSelf()方法,要么调用它的stopService()方法,否则该service将一直保持运行。
如果一个组件调用bindService()方法创建一个service,同时onStartCommand()方法未被调用的情况下,只要该组件一直绑定它,它就不会停止运行。直到所有绑定该service的组件都解除绑定之后,系统将销毁该service。
只有当内存不够用并且必须回收资源去响应用户焦点事件时,android系统将强制停止一个service。如果一个service被一个activity绑定,并且这个activity正拥有用户焦点,那么该service被系统杀死的可能性非常小。如果service被声明为前台运行,那么它几乎不会被系统杀死。
在manifest中声明一个service:
<manifest ... >
  ...
  <application ... >
      <service android:name=".ExampleService" />
      ...
  </application>
</manifest>
<service>标签中有几个属性,但是只有android:name属性是必须的。和activity一样,service也可以定义<intent-filter>。如果你只希望你的service只在自己的应用程序中使用,你可以通过设置android:exported为false。
创建一个已经开始的service:
一个已运行的service是指其他组件可以调用startService()方法,而系统自动调用onStartCommand()执行。当一个service已经运行,即使调用它的组件已经被销毁了,但它一直在后台运行。这样,service应该在工作完成之后调用stopSelf()自己销毁,或者通过其他组件调用stopService()进行销毁。
一个应用程序组件,例如activity,可以通过调用startService()启动一个service,同时传递一个Intent传递一些数据给service使用,service将在onStartCommand方法中接收Intent.
你可以通过继承两个类去创建一个开始的service:
Service:所有services的基类,当继承这个类时,特别需要注意的是,你应该创建一个新线程去完成这个service的工作。因为,在默认情况下,service使用的是应用程序的主线程,如果不把service的工作交给线程处理,那么将会严重影降低应用程序中其他正在运行的activity的效率。
IntentService:Service的子类,一个使用工作线程去出处理所有请求。如果你不需要你的service去同时处理多请求,那么最好继承该类实现service。而使用该类,你唯一需要做的事情就是,实现onHandleIntent()方法。该方法接收intent数据。
那么,在什么情况下选择继承IntentService类呢?
因为大多数开始的services不需要在同时处理多个情况(实际上处理多个请求....),继承IntentService类实现service是一个非常好的选择。
IntentService主要做了一下工作:
1、创建一个默认的工作线程去执行所有的Intent去调用onStartCommand(),这样就和主线程想分离。
2、创建一个工作队列,该队列一次只传递一个intent给你的onHandleIntent()方法,所以你永远不用顾虑多线程;
3、当所有请求都被处理之后停止service,所以,你永远不用调用stopSelf();
4、提供onBlind默认的实现,返回null;
5、提供onStartCommand()方法的默认实现,即发送intent给工作队列,然后调用onHandleIntent()实现。
所以,你最终只需要实现onHandlerIntent()方法去完成客户组件发送过来的请求即可。
public class HelloIntentService extends IntentService {


  /** 
   * A constructor is required, and must call the super IntentService(String)
   * constructor with a name for the worker thread.
   */
  public HelloIntentService() {
      super("HelloIntentService");
  }


  /**
   * The IntentService calls this method from the default worker thread with
   * the intent that started the service. When this method returns, IntentService
   * stops the service, as appropriate.
   */
  @Override
  protected void onHandleIntent(Intent intent) {
      // Normally we would do some work here, like download a file.
      // For our sample, we just sleep for 5 seconds.
      long endTime = System.currentTimeMillis() + 5*1000;
      while (System.currentTimeMillis() < endTime) {
          synchronized (this) {
              try {
                  wait(endTime - System.currentTimeMillis());
              } catch (Exception e) {
              }
          }
      }
  }
}
你先需要做的就是:重写构造方法和实现onHandlerIntent();
如果你仍然决定重写service的回调方法,比如onCreate(),onStartCommand(),或者onDestroy(),务必保证调用父类的实现,以便IntentService能恰当的处理工作线程的生命周期。例如:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent,flags,startId);
}


创建一个可以绑定的Service:


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Media
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
android多媒体框架包括对一些常用媒体类型的编码和解码工作,以便你能轻松的整合音频、视频和图片到应用程序中。你能播放你应用程序资源(raw)、单独的文件系统、或者来自于互联网的数据流中播放音频文件或视频文件,而这些操作都用MediaPlayer提供的api来完成。
你也可以使用MeidaRecorder提供的api完成录音,或录制视频的工作,当然前提是必须硬件支持。即便是模拟器不支持这些功能,真机设备可有可能提供这些功能。
该文档将教你如何写一个媒体播放应用程序,该程序在用户和系统之间进行交互,以便获取好的业绩和良好的用户体验。
注意:你只能在单独的输出设备中回放音频数据。……
+++++++++MediaPlayer的使用+++++++++++
媒体框架中一个最重要的组件是MediaPlayer类。该类的对象可以在最小的安装上抓取,解码,和播放音频和视频文件。并且,它支持很多不懂的媒体资源,比如:
本地资源;
Internal URI,比如你从Content Resolver中获取资源。
外部URLs(流资源)
播放音频文件示例:


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
App Widgets
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
App Widgets是微型应用视图应用程序,该应用程序能嵌入其他应用程序中(比如Home屏幕),并且接收周期性的更新。这些视图被称为用户接口小部件,并且你能发布一个带有App Widget provider的小部件。带有应用程序小部件的应用程序组件称为App Widget宿主。
--用App Widget provider发布一个应用程序小部件(App Widget)
基础:
=》为了创建一个App Widget,你需要完成:
1、一个AppWidgetProviderInfo对象,描述App Widget元数据,比如App Widget的布局文件,更新频率,和AppWidgetProvider类。这个应该在XML文件中定义。
2、一个AppWidgetProvider的实现类。定义一些主要方法,这些方法允许你从编程角度提供App Widget的接口,基于广播事件。通过它,你能在AppWidget更新,激活,未激活和删除情况下接收广播。
3、视图布局(View layout):为App Widget提供初始化布局XML文件。
4、另外,你能实现一个App Widget设置Activity。这个Activity是可选的。
=》详细介绍:
1、在你应用程序的AndroidMainfest.xml中声明一个AppWidgetProvider类,例如:
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
               android:resource="@xml/example_appwidget_info" />
</receiver>
这个<receiver>元素需要一个android:name属性,指明这个AppWidgetProvider被App Widget使用。
<intent-filter>元素必须包含一个<action>元素,该元素包含一个android:name属性。这个属性指定AppWidgetProvider接收ACTION_APPWIDGET_UPDATE广播。这是唯一一个你必须显示圣母庙的广播。必要时,AppWidgetManager自动发送所有App Widget广播给AppWidgetProvider.
<meta-data>元素指定AppWidgetProviderInfo资源,并且需要指明一下属性:
android:name,指定元数据名称。使用android.appwidget.provider作为AppWidgetProviderInfo描述器。
android:resource,指定AppWidgetProviderInfo资源位置。
2、增加AppWidgetProviderInfo元数据。AppWidgetInfo定义了一个App Widget的必要内容。比如最小化布局区域,它的初始化布局资源,和更新应用小部件的频率,以及在创建时设置的activity.在XML里定义AppWidgetProviderInfo,使用单个<appwidget-provider>元素即可,并且保存到工程的res/xml文件夹下。例如:
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="294dp"
    android:minHeight="72dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/preview"
    android:initialLayout="@layout/example_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode="horizontal|vertical">
</appwidget-provider>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值