38 votes

Activité de lancement depuis le widget

Je suis en train de faire quelque chose de vraiment devrait être assez facile, mais ça me rend fou. Je suis en train de lancer une activité lorsque l'écran d'accueil widget est pressé, comme une configuration d'activité pour le widget. Je pense que j'ai suivi mot pour mot le tutoriel sur le site des Développeurs Android, et même un peu officieux de tutoriels, mais je doit manquer quelque chose d'important qu'il ne fonctionne pas.

Voici le code:

public class VolumeChangerWidget extends AppWidgetProvider {

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
	final int N = appWidgetIds.length;

	for (int i=0; i < N; i++) {
		int appWidgetId = appWidgetIds[i];

		Log.d("Steve", "Running for appWidgetId " + appWidgetId);
		Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
		Log.d("Steve", "After the toast line");

		Intent intent = new Intent(context, WidgetTest.class);

		PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
		views.setOnClickPendingIntent(R.id.button, pendingIntent);

		appWidgetManager.updateAppWidget(appWidgetId, views);
	}
}

}

Lors de l'ajout d'un widget sur l'écran d'accueil, Logcat montre les deux lignes de débogage, mais pas le pain grillé. (Des idées pourquoi pas?) Toutefois, le plus difficile, c'est que lorsque je puis cliquez sur le bouton avec le PendingIntent associés avec elle, il ne se passe rien du tout. Je sais que le "WidgetTest" l'activité peut s'exécuter parce que si j'ai mis en place une Intention de la part dans l'activité principale, il se lance très bien.

En cas de questions, voici le fichier Manifeste Android:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.steve"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".Volume_Change_Program"
              android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

	<activity android:name=".WidgetTest"
			  android:label="@string/hello">
		<intent_filter>
			<action android:name="android.intent.action.MAIN"/>
			<category android:name="android.intent.category.LAUNCHER"/>
		</intent_filter>
	</activity>

    <receiver android:name=".VolumeChangerWidget" >
    	<intent-filter>
    		<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    	</intent-filter>
    	<meta-data 	android:name="android.appwidget.provider"
    				android:resource="@xml/volume_changer_info" />
    </receiver>

</application>
<uses-sdk android:minSdkVersion="3" />

Est-il un moyen pour tester où la faute est? I. e. la faute est que le bouton n'est pas correctement liés à la PendingIntent, ou que le PendingIntent ou l'Intention n'est pas de trouver WidgetTest.class, etc?

Merci beaucoup pour votre aide!

Steve

22voto

Brent Chartrand Points 401

En apportant cette manière de la mort, mais j'ai eu un problème similaire et je pense que j'ai enfin résolu... comme vous, j'ai eu un PendingIntent que j'ai attaché à la RemoteView. Parfois, il serait de travailler, et parfois, il serait un échec. Il a été me rend fou.

Ce que j'ai trouvé à partir d'une info-bulle sur le PendingIntent.getActivty() a été:

Notez que l'activité a commencé en dehors du contexte d'une activité existante, de sorte que vous devez utiliser de l'Intention.FLAG_ACTIVITY_NEW_TASK lancer de drapeau dans l'Intention.

donc, j'ai ajouté:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Aucun exemple de code que j'ai vu jusqu'à présent fait cela, mais il a résolu mon problème; les Paramètres de l'activité est maintenant lancé de manière fiable.

Le code complet qui fonctionne bien...

Intent intent = new Intent(context, Settings.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appId);  // Identifies the particular widget...
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// Make the pending intent unique...
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.wwwidget);
views.setOnClickPendingIntent(R.id.widget, pendIntent);
appWidgetManager.updateAppWidget(appId,views);

10voto

mylock Points 414

J'avais le même problème. J'ai découvert que le correctif consiste à appeler une mise à jour via le gestionnaire d'appwidget. Voici un exemple de la façon de faire cela dans onEnabled. Il semble que cela doit être fait à la fois sur onEnabled et onUpdated, de sorte que lorsque le périphérique est allumé, l'intention de clic est également intialisée - in onUpdated, les paramètres fournissent déjà la référence au gestionnaire, heureusement.

 @Override 
    public void onEnabled(Context context) {  
          //Log.v("toggle_widget","Enabled is being called"); 

          AppWidgetManager mgr = AppWidgetManager.getInstance(context); 
          //retrieve a ref to the manager so we can pass a view update 

          Intent i = new Intent(); 
          i.setClassName("yourdoman.yourpackage", "yourdomain.yourpackage.yourclass"); 
          PendingIntent myPI = PendingIntent.getService(context, 0, i, 0); 
          //intent to start service 

        // Get the layout for the App Widget 
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.togglelayout); 

        //attach the click listener for the service start command intent 
        views.setOnClickPendingIntent(R.id.toggleButton, myPI); 

        //define the componenet for self 
        ComponentName comp = new ComponentName(context.getPackageName(), ToggleWidget.class.getName()); 

        //tell the manager to update all instances of the toggle widget with the click listener 
        mgr.updateAppWidget(comp, views); 
} 
 

7voto

kpd Points 251

Cela a fonctionné pour moi, en fonction des informations ici, de l'exemple de widget mot et du tutoriel ici.

        Intent intent = new Intent(Intent.ACTION_MAIN, null);
      intent.addCategory(Intent.CATEGORY_LAUNCHER);
      // first param is app package name, second is package.class of the main activity
      ComponentName cn = new ComponentName("com....","com...MainActivity");
      intent.setComponent(cn);
      intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
      PendingIntent myPI = PendingIntent.getActivity(context, 0, intent, 0); 

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


    views.setOnClickPendingIntent(R.id.widget, myPI); 

    AppWidgetManager mgr = AppWidgetManager.getInstance(context); 
    mgr.updateAppWidget(comp, views); 
 

4voto

JohanS Points 41

Le problème avec le Toast qui ne se montre pas est facile, vous n’appelez pas show (), une erreur que je fais toujours aussi ...

 Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT).show();
 

au lieu de

 Toast.makeText(context, "Hello from onUpdate", Toast.LENGTH_SHORT);
 

1voto

Fedor Points 29890

Steve,

Avez-vous trouvé le problème? J'utilise un widget et cela fonctionne bien pour moi sans astuce onEnabled. Je suis intéressé pourquoi ce n'est pas pour vous.

Mon estimation: dans votre code d'origine, veuillez essayer

 PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
 

au lieu de

 PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X