Widget pour allumer / éteindre la lampe de poche de l'appareil photo dans android

je développe un widget pour allumer/éteindre caméra led de téléphone.

j'ai fait un widget qui peut fonctionner comme bouton à bascule (on/off).

se comporte comme suit : parfois, la lumière led reste allumée lorsque j'active le widget. Mais il n'allume pas/éteint la led de la caméra mais il change l'icône.

je ne suis pas en mesure de comprendre quel est le problème réel.

La même chose fonctionne bien en Activité (Application De La Lampe Torche).

est-ce que quelqu'un peut m'expliquer comment je peux résoudre mon problème ?

Où je vais mal ?

Vous pouvez regarder le code ci-dessous que j'ai fait jusqu'à présent

onUpdate méthode

@Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {

         //super.onUpdate(context, appWidgetManager, appWidgetIds);

        remoteViews = new RemoteViews( context.getPackageName(), R.layout.widgetlayout);
        watchWidget = new ComponentName( context, FlashLightWidget.class );

        Intent intentClick = new Intent(context,FlashLightWidget.class);
        intentClick.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, ""+appWidgetIds[0]);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[0],intentClick, 0);
        remoteViews.setOnClickPendingIntent(R.id.myToggleWidget, pendingIntent);
        appWidgetManager.updateAppWidget( watchWidget, remoteViews );
        ctx=context;      
    }

onReceive méthode est la suivante:

@Override

    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub

        remoteViews = new RemoteViews( context.getPackageName(), R.layout.widgetlayout);
        if (intent.getAction()==null) {
            Bundle extras = intent.getExtras();
            if(extras!=null) {
                 if(status)
                    {
                        status=false;
                        remoteViews.setImageViewResource(R.id.myToggleWidget, R.drawable.shutdown1);
                        processOnClick();
                        Toast.makeText(context,"Status==false-onclick",Toast.LENGTH_SHORT).show();
                    }
                    else
                    {
                        status = true;
                        remoteViews.setImageViewResource(R.id.myToggleWidget, R.drawable.shutdown2);
                        processOffClick();
                        Toast.makeText(context,"Status==true--Ofclick",Toast.LENGTH_SHORT).show();
                    }
                }

                watchWidget = new ComponentName( context, FlashLightWidget.class );

                (AppWidgetManager.getInstance(context)).updateAppWidget( watchWidget, remoteViews );
           }
        }
  }

processOffClick méthode

private void processOffClick() {

        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mCamera.release();      
            mCamera = null;
        }
    }

processOnClick méthode

private void processOnClick() {

    if(mCamera==null)
    {
        try {
            mCamera = Camera.open();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    if (mCamera != null) {

        Parameters params = mCamera.getParameters();
        List<String> flashModes = params.getSupportedFlashModes();

        if (flashModes == null) {
            return;
        } else {

                params.setFlashMode(Parameters.FLASH_MODE_OFF);
                mCamera.setParameters(params);
                mCamera.startPreview();

            String flashMode = params.getFlashMode();

            if (!Parameters.FLASH_MODE_TORCH.equals(flashMode)) {

                if (flashModes.contains(Parameters.FLASH_MODE_TORCH)) {
                    params.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    mCamera.setParameters(params);

                } 

            }
        }
    } else if (mCamera == null) {
        //Toast.makeText(ctx, "Camera not found", Toast.LENGTH_LONG).show();
        return;
    }
}
37
demandé sur Kartik Domadiya 2011-09-22 17:14:27

4 réponses

après un long moment, j'ai été libre de résoudre ce problème.

voilà ce que j'ai fait.

FlashlightWidgetProvider classe:

public class FlashlightWidgetProvider extends AppWidgetProvider {

        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager,
                        int[] appWidgetIds) {

                Intent receiver = new Intent(context, FlashlightWidgetReceiver.class);
                receiver.setAction("COM_FLASHLIGHT");
                receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
                PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, receiver, 0);

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

                appWidgetManager.updateAppWidget(appWidgetIds, views);

        }
}

et "BroadcastReceiver for FlashlightWidgetReceiver:

public class FlashlightWidgetReceiver extends BroadcastReceiver {
            private static boolean isLightOn = false;
            private static Camera camera;

            @Override
            public void onReceive(Context context, Intent intent) {
                    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

                    if(isLightOn) {
                            views.setImageViewResource(R.id.button, R.drawable.off);
                    } else {
                            views.setImageViewResource(R.id.button, R.drawable.on);
                    }

                    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
                    appWidgetManager.updateAppWidget(new ComponentName(context,     FlashlightWidgetProvider.class),
                                                                                     views);

                    if (isLightOn) {
                            if (camera != null) {
                                    camera.stopPreview();
                                    camera.release();
                                    camera = null;
                                    isLightOn = false;
                            }

                    } else {
                            // Open the default i.e. the first rear facing camera.
                            camera = Camera.open();

                            if(camera == null) {
                                    Toast.makeText(context, R.string.no_camera, Toast.LENGTH_SHORT).show();
                            } else {
                                    // Set the torch flash mode
                                    Parameters param = camera.getParameters();
                                    param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                                    try {
                                            camera.setParameters(param);
                                            camera.startPreview();
                                            isLightOn = true;
                                    } catch (Exception e) {
                                            Toast.makeText(context, R.string.no_flash, Toast.LENGTH_SHORT).show();
                                    }
                            }
                    }
            }
    }

Permission requise dans Manifest.xml fichier:

<uses-permission android:name="android.permission.CAMERA"></uses-permission>

enregistre également les récepteurs dans Manifest.xml fichier:

<receiver android:name=".FlashlightWidgetProvider" android:icon="@drawable/on" android:label="@string/app_name">
         <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
         </intent-filter>

         <meta-data android:name="android.appwidget.provider"
                        android:resource="@xml/flashlight_appwidget_info" />
</receiver>

<receiver android:name="FlashlightWidgetReceiver">
        <intent-filter>
               <action android:name="COM_FLASHLIGHT"></action>
        </intent-filter>
 </receiver>

Note importante : ce code fonctionne parfaitement si votre téléphone a FLASH_MODE_TORCH pris en charge.

j'ai testé dans Samsung Galaxy Ace 2.2.1 & 2.3.3. Le code ne fonctionne pas car ce périphérique N'a pas de FLASH_MODE_TORCH.

fonctionne très bien dans HTC Salsa, Wildfire..

Si quelqu'un peut tester et de publier les résultats ici, ce serait mieux.

40
répondu Kartik Domadiya 2012-12-31 08:28:42

la meilleure technique pour gérer les clics d'un RemoteViews est de créer un PendingIntent qui appelle un service, et effectuer le "truc" que vous voulez dans le service, y compris toutes les mises à jour RemoteViews supplémentaires pour votre widget. Vous pouvez envoyer les données pertinentes à l'intention des extras. Le service appelle stopSelf() à la fin, donc il s'arrête.

vous ne pouvez maintenir aucun État dans un BroadcastReceiver ; le système exécute ceux sur n'importe quel fil disponible, et ne conserve aucune référence à votre instance après avoir appelé onReceive() . Votre variable mCamera n'est pas garantie d'être maintenue entre les invocations de votre BroadcastReceiver .

si vous avez vraiment besoin de maintenir l'état, vous devez le faire dans le service, et ne pas utiliser stopSelf() (jusqu'à un moment approprié).

vous n'avez pas besoin D'un thread pour utiliser la classe Camera , à moins que vous ne fassiez un aperçu d'image, qui nécessite un SurfaceHolder (et implique une assurance-chômage). Vous devez cependant avoir une boucle d'événement active, ou Camera ne vous affichera pas de callbacks, ce qui est un problème puisque Camera est principalement asynchrone. Vous pouvez le faire dans le cadre d'un service (voir HandlerThread ) et garder votre service actif jusqu'à ce qu'il soit temps de release() tout. Quel que soit le thread qui appelle Camera.open() , il recevra des callbacks.

est-ce que tout le monde a lu la section sur les Widgets D'application? http://developer.android.com/guide/topics/appwidgets/index.html

en utilisant la classe AppWidgetProvider section dit à peu près ce que je dis ici.

6
répondu escape-llc 2011-10-25 16:48:35

j'ai eu une situation similaire où je dois exécuter certains Code android sur le fil UI ... qui n'est disponible que dans une activité. Ma solution-une activité avec une mise en page complètement transparente. Donc, vous ne voyez que votre écran d'accueil (bien que ne réagissant pas) pendant que vous terminez vos actions, ce qui dans votre cas devrait être assez rapide.

2
répondu Yossi 2011-10-12 02:47:43

j'ai une solution qui n'est pas grand, mais fonctionne. Demandez au widget d'appeler une activité, et dans L'activité allumez le flash, et plus tard fermez l'activité. De même pour l'éteindre. Si cela fonctionne, dans l'Activité, alors cette solution fonctionne. Ce n'est pas élégant, mais fonctionne. Je l'ai essayé.

1
répondu titusfx 2011-10-10 06:00:09