0

我一直在試圖製作一個Android小部件,它只是一個帶有用戶定義顏色的TextClock。但是,啓動程序重新啓動後,TextClock的顏色總是會恢復爲白色,並且不會保留用戶定義的顏色。這是我第一次製作一個Android小部件,並且我一直在試圖弄清楚爲什麼會發生這些事情,我已經把頭髮拉出了幾天。Android:創建彩色TextClock小部件

所以,

配置活動:

public class MainActivity extends Activity { 
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setResult(RESULT_CANCELED); 
    setContentView(R.layout.main_activity); 

    Intent intent = getIntent(); 
    Bundle extras = intent.getExtras(); 
    if (extras != null) { 
     mAppWidgetId = extras.getInt(
       AppWidgetManager.EXTRA_APPWIDGET_ID, 
       AppWidgetManager.INVALID_APPWIDGET_ID); 
    } 
    // If they gave us an intent without the widget id, just bail. 
    if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) { 
     finish(); 
    } 

    OnCancelListener cancelListener = new OnCancelListener() 
    { 
     @Override 
     public void onCancel(DialogInterface dialog) 
     { 
      MainActivity.this.finish(); 
     } 
    }; 

    OnColorChangedListener ccListener = new ColorPickerDialog.OnColorChangedListener(){ 

     @Override 
     public void onColorChanged(int color) { 
      PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit().putInt("color", color).apply(); 
      getSharedPreferences("" + mAppWidgetId, MODE_PRIVATE).edit().putInt("color", color).apply(); 

      AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(MainActivity.this); 
      MyWidget.updateAppWidget(MainActivity.this, appWidgetManager, mAppWidgetId, color); 
      Intent resultValue = new Intent(); 
      resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); 
      setResult(RESULT_OK, resultValue); 
      finish(); 
     } 

    }; 

    int initialColor = PreferenceManager.getDefaultSharedPreferences(this).getInt("color", Color.RED); 

    ColorPickerDialog cpd = new ColorPickerDialog(this, initialColor); 
    cpd.setHexValueEnabled(true); 
    cpd.setAlphaSliderVisible(true); 
    cpd.setOnColorChangedListener(ccListener); 
    cpd.setOnCancelListener(cancelListener); 
    cpd.show(); 


} 

} 

所述的AppWidgetProvider:

public class MyWidget extends AppWidgetProvider{ 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    super.onUpdate(context, appWidgetManager, appWidgetIds); 
    Log.d("Hey", "onUpdate"); 
    final int N = appWidgetIds.length; 
    for (int i=0; i<N; i++) { 
     int appWidgetId = appWidgetIds[i]; 
     int color = context.getSharedPreferences("" + appWidgetId, Context.MODE_PRIVATE).getInt("color", Color.RED); 
     updateAppWidget(context, appWidgetManager, appWidgetId, color); 
    } 
} 

@Override 
public void onDeleted(Context context, int[] appWidgetIds) { 
    super.onDeleted(context, appWidgetIds); 
    // When the user deletes the widget, delete the preference associated with it. 
    final int N = appWidgetIds.length; 
    for (int i=0; i<N; i++) { 
     int appWidgetId = appWidgetIds[i]; 
     context.getSharedPreferences("" + appWidgetId, Context.MODE_PRIVATE).edit().clear().apply(); 
    } 
} 

@Override 
public void onAppWidgetOptionsChanged (Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions){ 
    super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); 
    Log.d("updating", "updating"); 
    int nwidth = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH) - newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); 
    int nheight = newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT) - newOptions.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); 
    Log.d("nheight", "" + nheight); 
    Log.d("nwidth", "" + nwidth); 

    RemoteViews views = new RemoteViews(context.getPackageName(), 
      R.layout.activity_main); 

    PackageManager packageManager = context.getPackageManager(); 
    Intent alarmClockIntent = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER); 
    // Verify clock implementation 
    String clockImpls[][] = { 
      {"HTC Alarm Clock", "com.htc.android.worldclock", "com.htc.android.worldclock.WorldClockTabControl" }, 
      {"Standard Alarm Clock", "com.android.deskclock", "com.android.deskclock.AlarmClock"}, 
      {"Froyo Nexus Alarm Clock", "com.google.android.deskclock", "com.android.deskclock.DeskClock"}, 
      {"Moto Blur Alarm Clock", "com.motorola.blur.alarmclock", "com.motorola.blur.alarmclock.AlarmClock"}, 
      {"Samsung Galaxy Clock", "com.sec.android.app.clockpackage","com.sec.android.app.clockpackage.ClockPackage"} 
    }; 
    boolean foundClockImpl = false; 
    for(int i=0; i<clockImpls.length; i++) { 
     String vendor = clockImpls[i][0]; 
     String packageName = clockImpls[i][1]; 
     String className = clockImpls[i][2]; 
     try { 
      ComponentName cn = new ComponentName(packageName, className); 
      ActivityInfo aInfo = packageManager.getActivityInfo(cn, PackageManager.GET_META_DATA); 
      alarmClockIntent.setComponent(cn); 
      Log.d("Clock", "Found " + vendor + " --> " + packageName + "/" + className + "."); 
      foundClockImpl = true; 
     } catch (NameNotFoundException e) { 
      Log.d("Clock", vendor + " does not exists."); 
     } 
    } 
    if (foundClockImpl) { 
     PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, alarmClockIntent, 0); 
      // add pending intent to your component 
      // .... 
     views.setOnClickPendingIntent(R.id.textClock, pendingIntent); 
    } 

    if (nwidth >= 60 || nwidth==0){ 
     views.setTextViewTextSize(R.id.textClock, TypedValue.COMPLEX_UNIT_SP, 48); 
    } else if(nwidth >= 40){ 
     views.setTextViewTextSize(R.id.textClock, TypedValue.COMPLEX_UNIT_SP, 26); 
    } else{ 
     views.setTextViewTextSize(R.id.textClock, TypedValue.COMPLEX_UNIT_SP, 12); 
    } 
    appWidgetManager.updateAppWidget(appWidgetId, views); 
} 


static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, 
     int appWidgetId, int color) { 

    // Construct the RemoteViews object. It takes the package name (in our case, it's our 
    // package, but it needs this because on the other side it's the widget host inflating 
    // the layout from our package). 
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main); 
    views.setTextColor(R.id.textClock, color); 

    // Tell the widget manager 
    appWidgetManager.updateAppWidget(appWidgetId, views); 
} 

} 

activity_main.xml中(佈局窗口小部件):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" > 

<TextClock 
    android:id="@+id/textClock" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:gravity="center" 

    android:textSize="26sp" 
/> 

</RelativeLayout> 

的appw idget_info.xml:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
android:minWidth="80dp" 
android:minHeight="40dp" 
android:minResizeWidth="20dp" 
android:minResizeHeight="20dp" 
android:updatePeriodMillis="0" 
android:previewImage="@drawable/ic_launcher" 
android:initialLayout="@layout/activity_main" 
android:configure="com.brianco.colorclock.MainActivity" 
android:resizeMode="horizontal|vertical" 
android:widgetCategory="home_screen|keyguard" 
android:initialKeyguardLayout="@layout/activity_main"> 
</appwidget-provider> 

...並在AndroidManifest.xml:

<application 
    android:allowBackup="true" 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:name="com.brianco.colorclock.MainActivity" 
     android:label="@string/app_name" 
     android:theme="@android:style/Theme.Translucent.NoTitleBar" > 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> 
     </intent-filter> 
    </activity> 

    <receiver android:name="com.brianco.colorclock.MyWidget" > 
     <intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
     </intent-filter> 
     <meta-data android:name="android.appwidget.provider" 
       android:resource="@xml/appwidget_info" /> 
    </receiver> 
</application> 

任何瞭解爲什麼從配置活動的設置不是「堅持」將不勝感激。我希望如果我解決了這個問題,就可以開源這個應用程序,所以其他人可以學習。

回答

0

好吧,我認爲問題是調用appWidgetManager.updateAppWidget(appWidgetId,views);當新的RemoteView對象(視圖)沒有調用它時調用.setTextColor(color)。我希望能幫助別人。 彩色時鐘應用程序源(GPLv3):https://github.com/NightlyNexus/Color-Clock