2017-02-11 4 views
2

저는 실행기 개발자이며 위젯에 대한 기초는 항상 내가 찾은이 간단한 안내서를 따라 왔습니다 : Hosting Android Widgets. 이제이 방법은 데모 앱을 사용할 때 100 % 작동합니다. 문제는 AppCompat 테마를 추가하고 의 최신 com.android.support:appcompat-v7:25.1.1이 아닌 AppCompatActivity을 확장하자마자 문제가 발생합니다. 또한AppCompat는 런처 위젯 기능을 중단합니다. "오류보기를 사용하여 어떤보기도 찾을 수 없습니다."

W/AppWidgetHostView: updateAppWidget couldn't find any view, using error view android.widget.RemoteViews$ActionException: view: android.support.v7.widget.AppCompatImageView can't use method with RemoteViews: setImageResource(int) 
at android.widget.RemoteViews.getMethod(RemoteViews.java:775) 
at android.widget.RemoteViews.access$300(RemoteViews.java:69) 
at android.widget.RemoteViews$ReflectionAction.apply(RemoteViews.java:1266) 
at android.widget.RemoteViews.performApply(RemoteViews.java:2587) 
at android.widget.RemoteViews.apply(RemoteViews.java:2547) 
at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:395) 
at android.appwidget.AppWidgetHost.createView(AppWidgetHost.java:336) 
at com.lgfischer.widgethost.WidgetHostExampleActivity.createWidget(WidgetHostExampleActivity.java:129) 
at com.lgfischer.widgethost.WidgetHostExampleActivity.onActivityResult(WidgetHostExampleActivity.java:93) 
at android.app.Activity.dispatchActivityResult(Activity.java:6168) 
at android.app.ActivityThread.deliverResults(ActivityThread.java:3732) 
at android.app.ActivityThread.handleSendResult(ActivityThread.java:3779) 
at android.app.ActivityThread.access$1300(ActivityThread.java:162) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1461) 
at android.os.Handler.dispatchMessage(Handler.java:106) 
at android.os.Looper.loop(Looper.java:189) 
at android.app.ActivityThread.main(ActivityThread.java:5529) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:950) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:745) 

AppWidgetHostView 표시 "Couldn't add widget" 다음과 같이 ACTION_APPWIDGET_PICK 대화 상자에서 특정 위젯을 선택하면, 나는 오류가 발생합니다. 오류 로그에 따라 당연히 WidgetHostExampleActivity.java line #129을 살펴 보 겠지만 간단히 mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);을 호출하는 것입니다.

코드는 appcompat-v7:22.1.1에서 작동하지만 그 이상은 작동하지 않는 것 같습니다.

참고 :

  1. 나는 시험과 Android 5.0.2Android 7.1.1이 일부 위젯이 발생
  2. 에이 오류를 확인했다. 실패한 일부는 Default Calendar appAndroid 7.1.1이고 Play - My Library은 플레이 스토어 위젯입니다. 난 아직도

내가 내가 여기에 위에서 언급 한 수정이 프로젝트의 전체 소스 코드를 설명하는 문제를 가지고있는 사용자 정의 위젯을 선택 활동을 생성 한 플레이 스토어에서 내 실제 실행에

  • : Google Drive

    여기

    는 전체 WidgetHostExampleActivity입니다 : 여기

    public class WidgetHostExampleActivity extends AppCompatActivity{ 
    
    
        final static int APPWIDGET_HOST_ID = 111; 
        final static int REQUEST_PICK_APPWIDGET = 222; 
        final static int REQUEST_CREATE_APPWIDGET = 333; 
    
        static final String TAG = "WidgetHostExampleActivity"; 
    
        AppWidgetManager mAppWidgetManager; 
        AppWidgetHost mAppWidgetHost; 
    
        ViewGroup mainlayout; 
    
        /** 
        * Called on the creation of the activity. 
        */ 
        @Override 
        public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         setContentView(R.layout.main); 
    
         mainlayout = (ViewGroup) findViewById(R.id.main_layout); 
    
         mAppWidgetManager = AppWidgetManager.getInstance(this); 
         mAppWidgetHost = new AppWidgetHost(this, APPWIDGET_HOST_ID); 
        } 
    
        /** 
        * Launches the menu to select the widget. The selected widget will be on 
        * the result of the activity. 
        */ 
        void selectWidget() { 
         int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId(); 
         Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK); 
         pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 
         addEmptyData(pickIntent); 
         startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET); 
        } 
    
        /** 
        * This avoids a bug in the com.android.settings.AppWidgetPickActivity, 
        * which is used to select widgets. This just adds empty extras to the 
        * intent, avoiding the bug. 
        * 
        * See more: http://code.google.com/p/android/issues/detail?id=4272 
        */ 
        void addEmptyData(Intent pickIntent) { 
         ArrayList<AppWidgetProviderInfo> customInfo = new ArrayList<AppWidgetProviderInfo>(); 
         pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo); 
         ArrayList<Bundle> customExtras = new ArrayList<Bundle>(); 
         pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras); 
        } 
    
        /** 
        * If the user has selected an widget, the result will be in the 'data' when 
        * this function is called. 
        */ 
        @Override 
        protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
         if (resultCode == RESULT_OK) { 
          if (requestCode == REQUEST_PICK_APPWIDGET) { 
           configureWidget(data); 
          } else if (requestCode == REQUEST_CREATE_APPWIDGET) { 
           createWidget(data); 
          } 
         } else if (resultCode == RESULT_CANCELED && data != null) { 
          int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); 
          if (appWidgetId != -1) { 
           mAppWidgetHost.deleteAppWidgetId(appWidgetId); 
          } 
         } 
        } 
    
        /** 
        * Checks if the widget needs any configuration. If it needs, launches the 
        * configuration activity. 
        */ 
        private void configureWidget(Intent data) { 
         Bundle extras = data.getExtras(); 
         int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); 
         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); 
         if (appWidgetInfo.configure != null) { 
          Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); 
          intent.setComponent(appWidgetInfo.configure); 
          intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); 
          startActivityForResult(intent, REQUEST_CREATE_APPWIDGET); 
         } else { 
          createWidget(data); 
         } 
        } 
    
        /** 
        * Creates the widget and adds to our view layout. 
        */ 
        public void createWidget(Intent data) { 
         Bundle extras = data.getExtras(); 
         int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1); 
         AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId); 
    
         AppWidgetHostView hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo); 
         hostView.setAppWidget(appWidgetId, appWidgetInfo); 
         mainlayout.addView(hostView); 
    
         Log.i(TAG, "The widget size is: " + appWidgetInfo.minWidth + "*" + appWidgetInfo.minHeight); 
        } 
    
        /** 
        * Registers the AppWidgetHost to listen for updates to any widgets this app 
        * has. 
        */ 
        @Override 
        protected void onStart() { 
         super.onStart(); 
         mAppWidgetHost.startListening(); 
        } 
    
        /** 
        * Stop listen for updates for our widgets (saving battery). 
        */ 
        @Override 
        protected void onStop() { 
         super.onStop(); 
         mAppWidgetHost.stopListening(); 
        } 
    
        /** 
        * Removes the widget displayed by this AppWidgetHostView. 
        */ 
        public void removeWidget(AppWidgetHostView hostView) { 
         mAppWidgetHost.deleteAppWidgetId(hostView.getAppWidgetId()); 
         mainlayout.removeView(hostView); 
        } 
    
        /** 
        * Handles the menu. 
        */ 
        @Override 
        public boolean onOptionsItemSelected(MenuItem item) { 
         Log.i(TAG, "Menu selected: " + item.getTitle() + "/" + item.getItemId() + "/" + R.id.addWidget); 
         switch (item.getItemId()) { 
         case R.id.addWidget: 
          selectWidget(); 
          return true; 
         case R.id.removeWidget: 
          removeWidgetMenuSelected(); 
          return false; 
         } 
         return super.onOptionsItemSelected(item); 
        } 
    
        /** 
        * Handle the 'Remove Widget' menu. 
        */ 
        public void removeWidgetMenuSelected() { 
         int childCount = mainlayout.getChildCount(); 
         if (childCount > 1) { 
          View view = mainlayout.getChildAt(childCount - 1); 
          if (view instanceof AppWidgetHostView) { 
           removeWidget((AppWidgetHostView) view); 
           Toast.makeText(this, R.string.widget_removed_popup, Toast.LENGTH_SHORT).show(); 
           return; 
          } 
         } 
         Toast.makeText(this, R.string.no_widgets_popup, Toast.LENGTH_SHORT).show(); 
        } 
    
        /** 
        * Creates the menu with options to add and remove widgets. 
        */ 
        @Override 
        public boolean onCreateOptionsMenu(Menu menu) { 
         MenuInflater inflater = getMenuInflater(); 
         inflater.inflate(R.menu.widget_menu, menu); 
         return true; 
        } 
    } 
    

    settings.gradel입니다 :

    ,536,913,632 10
    apply plugin: 'com.android.application' 
    
    android { 
        compileSdkVersion 25 
        buildToolsVersion "25.0.2" 
    
        defaultConfig { 
         applicationId "com.lgfischer.widgethost" 
         minSdkVersion 11 
         targetSdkVersion 22 
    
        } 
    
        buildTypes { 
         release { 
          minifyEnabled false 
          shrinkResources false 
          proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 
         } 
        } 
    } 
    
    
    dependencies { 
        compile 'com.android.support:appcompat-v7:25.1.1' 
    } 
    

    추신 : 나는 지금 당장 질문을 게시하지 않으므로 내가 할 때 그것이 진짜 문제라는 것을 알고 있습니다.

  • 답변

    7

    관리자 및 호스트의 컨텍스트를 활동 컨텍스트가 아닌 응용 프로그램 컨텍스트로 변경하십시오.

    AppWidgetManager = AppWidgetManager.getInstance(getApplicationContext()); 
    mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID); 
    

    그 문제가 해결되었습니다.

    +0

    안드로이드 5.0.2에서는 작동하지만 안드로이드 7.1.1에서는 작동하지 않습니다. –

    +3

    EDIT : OK :이 작업은 다음과 같은 경우에도 가능합니다 : "mAppWidgetHost.createView (getApplicationContext(), appWidgetId, appWidgetInfo);" –

    +0

    그래, 안드로이드 7.x에서 나에게 잘 됐어. – dasfima