Android的Launcher启动器中添加快捷方式及小部件实例

2019-12-10 18:54:46王旭

也是两步走:

第一步:  发送Action为ACTION_APPWIDGET_PICK的 Intent ,则所有能创建窗口小部件的AppWidgetProvider的广播
接收者都会显示 ,同时为该新创建的AppWidget分配一个appWidgetId ,该appWidgetId即可唯一标记我们选择的
AppWidget。

第二步:如果选择的AppWidget对应地AppWidgetProviderInfo对象配置了android:configure属性,则需要在此启动该配置
属性(一般为一个Activity类) ,然后在完成添加AppWidget的操作 ; 否则,没有配置android:configure属性,就可以添加
AppWidget的操作。

示例Demo截图:

Android的Launcher启动器中添加快捷方式及小部件实例

主工程流程如下:  

package com.qin.addappwidget; 
 
 
import android.app.Activity; 
import android.appwidget.AppWidgetHost; 
import android.appwidget.AppWidgetHostView; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProviderInfo; 
import android.content.Intent; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.TextView; 
import android.widget.Toast; 
 
public class MainActivity extends Activity 
{ 
 
 private static String TAG = "AddAppWidget" ; 
  
 private Button btAddShortCut; 
 private LinearLayout linearLayout ; // 装载Appwidget的父视图 
  
 private static final int MY_REQUEST_APPWIDGET = 1; 
 private static final int MY_CREATE_APPWIDGET = 2; 
  
 private static final int HOST_ID = 1024 ; 
  
 private AppWidgetHost mAppWidgetHost = null ; 
 AppWidgetManager appWidgetManager = null; 
  
 /** Called when the activity is first created. */ 
 @Override 
 public void onCreate(Bundle savedInstanceState) 
 { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
 
  btAddShortCut = (Button) findViewById(R.id.bt_addShortcut); 
 
  linearLayout = (LinearLayout)findViewById(R.id.linearLayout) ; 
  
  //其参数hostid大意是指定该AppWidgetHost 即本Activity的标记Id, 直接设置为一个整数值吧 。 
  mAppWidgetHost = new AppWidgetHost(MainActivity.this, HOST_ID) ; 
   
  //为了保证AppWidget的及时更新 , 必须在Activity的onCreate/onStar方法调用该方法 
  // 当然可以在onStop方法中,调用mAppWidgetHost.stopListenering() 停止AppWidget更新 
  mAppWidgetHost.startListening() ; 
   
  //获得AppWidgetManager对象 
  appWidgetManager = AppWidgetManager.getInstance(MainActivity.this) ; 
   
   
  btAddShortCut.setOnClickListener(new View.OnClickListener() 
  { 
   @Override 
   public void onClick(View v) 
   { 
     //显示所有能创建AppWidget的列表 发送此 ACTION_APPWIDGET_PICK 的Action 
     Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK) ; 
     
     //向系统申请一个新的appWidgetId ,该appWidgetId与我们发送Action为ACTION_APPWIDGET_PICK 
     // 后所选择的AppWidget绑定 。 因此,我们可以通过这个appWidgetId获取该AppWidget的信息了 
     
     //为当前所在进程申请一个新的appWidgetId 
     int newAppWidgetId = mAppWidgetHost.allocateAppWidgetId() ; 
     Log.i(TAG, "The new allocate appWidgetId is ----> " + newAppWidgetId) ; 
     
     //作为Intent附加值 , 该appWidgetId将会与选定的AppWidget绑定     
     pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, newAppWidgetId) ; 
     
     //选择某项AppWidget后,立即返回,即回调onActivityResult()方法 
     startActivityForResult(pickIntent , MY_REQUEST_APPWIDGET) ; 
         
   } 
  }); 
 } 
 
 // 如果 
 protected void onActivityResult(int requestCode, int resultCode, Intent data) 
 { 
  //直接返回,没有选择任何一项 ,例如按Back键 
  if(resultCode == RESULT_CANCELED) 
   return ; 
   
  switch(requestCode){ 
   case MY_REQUEST_APPWIDGET : 
    Log.i(TAG, "MY_REQUEST_APPWIDGET intent info is -----> "+data ) ; 
    int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID , AppWidgetManager.INVALID_APPWIDGET_ID) ; 
     
    Log.i(TAG, "MY_REQUEST_APPWIDGET : appWidgetId is ----> " + appWidgetId) ; 
     
    //得到的为有效的id 
    if(appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID){ 
     //查询指定appWidgetId的 AppWidgetProviderInfo对象 , 即在xml文件配置的<appwidget-provider />节点信息 
     AppWidgetProviderInfo appWidgetProviderInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) ; 
      
     //如果配置了configure属性 , 即android:configure = "" ,需要再次启动该configure指定的类文件,通常为一个Activity 
     if(appWidgetProviderInfo.configure != null){ 
       
      Log.i(TAG, "The AppWidgetProviderInfo configure info -----> " + appWidgetProviderInfo.configure ) ; 
       
      //配置此Action 
      Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE) ; 
      intent.setComponent(appWidgetProviderInfo.configure) ; 
      intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 
       
       
      startActivityForResult(intent , MY_CREATE_APPWIDGET) ;     
     } 
     else //直接创建一个AppWidget 
      onActivityResult(MY_CREATE_APPWIDGET , RESULT_OK , data) ; //参数不同,简单回调而已       
    }    
    break ; 
   case MY_CREATE_APPWIDGET: 
    completeAddAppWidget(data) ; 
    break ; 
  } 
   
 } 
  
 //向当前视图添加一个用户选择的 
 private void completeAddAppWidget(Intent data){ 
  Bundle extra = data.getExtras() ; 
  int appWidgetId = extra.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID , -1) ; 
  //等同于上面的获取方式 
  //int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID , AppWidgetManager.INVALID_APPWIDGET_ID) ; 
   
  Log.i(TAG, "completeAddAppWidget : appWidgetId is ----> " + appWidgetId) ; 
   
  if(appWidgetId == -1){ 
   Toast.makeText(MainActivity.this, "添加窗口小部件有误", Toast.LENGTH_SHORT) ; 
   return ; 
  } 
   
  AppWidgetProviderInfo appWidgetProviderInfo = appWidgetManager.getAppWidgetInfo(appWidgetId) ; 
   
  AppWidgetHostView hostView = mAppWidgetHost.createView(MainActivity.this, appWidgetId, appWidgetProviderInfo); 
     
  //linearLayout.addView(hostView) ; 
   
  int widget_minWidht = appWidgetProviderInfo.minWidth ; 
  int widget_minHeight = appWidgetProviderInfo.minHeight ; 
  //设置长宽 appWidgetProviderInfo 对象的 minWidth 和 minHeight 属性 
  LinearLayout.LayoutParams linearLayoutParams = new LinearLayout.LayoutParams(widget_minWidht, widget_minHeight); 
  //添加至LinearLayout父视图中 
  linearLayout.addView(hostView,linearLayoutParams) ;   
 } 
}