2017-09-25 2 views
0

Implémentation de weakfulIntentService dans xamarin.android. Problème lors de la lecture du fichier de métadonnées. eturn null lors de la lecture du fichier xml metadatafile dans BroadCastReceiver.Erreur lors de la lecture du fichier metadata à l'aide de activityInfo.LoadXmlMetaData()

** lecteur XmlReader = activityInfo.LoadXmlMetaData (PackageManager, WAKEFUL_META_DATA) **;

BroadcastReceiver

namespace Squarelabs.Droid 
{ 
[BroadcastReceiver] 
public class AlarmReceiver : BroadcastReceiver 
{ 
    private static string WAKEFUL_META_DATA = "squrelabs.inspection"; 
    public override void OnReceive(Context context, Intent intent) 
    { 
     WakefulIntentService.IAlarmListener alarmListener = 
     GetListener(context); 

     if (alarmListener != null) 
     { 
      if (intent.Action == null) 
      { 

       alarmListener.SendWakefulWork(context); 
      } 
      else 
      { 
       WakefulIntentService.ScheduleAlarms(alarmListener, context, true); 
      } 
     } 
    } 

    private WakefulIntentService.IAlarmListener GetListener(Context context) 
    { 
     PackageManager packageManager = context.PackageManager; 
     ComponentName componentName = new ComponentName(context, Class); 

     try 
     { 
      ActivityInfo activityInfo = packageManager.GetReceiverInfo(componentName, PackageInfoFlags.MetaData); 

      XmlReader reader = activityInfo.LoadXmlMetaData(packageManager, WAKEFUL_META_DATA); 

      while (reader!=null) 
      { 
       if (reader.IsStartElement()) 
       { 
        if (reader.Name == "WakefulIntentService") 
        { 
         string className = reader.Value; 
         Class cls = Java.Lang.Class.ForName(className); 
         return ((WakefulIntentService.IAlarmListener)cls.NewInstance()); 
        } 
       } 
       reader.MoveToNextAttribute(); 
      } 

     } catch (NameNotFoundException e) { 
     throw new RuntimeException("Cannot find own info???", e); 
     } catch (XmlPullParserException e) { 
     throw new RuntimeException("Malformed metadata resource XML", e); 
     } catch (IOException e) { 
     //throw new RuntimeException("Could not read resource XML", e); 
     } catch (ClassNotFoundException e) { 
     throw new RuntimeException("Listener class not found", e); 
     } catch (IllegalAccessException e) { 
     throw new RuntimeException("Listener is not public or lacks public constructor", e); 
     } catch (InstantiationException e) { 
     throw new RuntimeException("Could not create instance of listener", e); 
     } 
     return (null); 
    } 
} 

manifeste

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" android:versionCode="2" android:versionName="1.9.5" package="squrelabs.inspection"> 
<uses-sdk android:minSdkVersion="15" /> 

    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" /> 
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

    <application android:label="Squarelabs" android:icon="@drawable/icon"> 
<receiver android:name="AlarmReceiver"> 
    <intent-filter> 
     <action android:name="android.intent.action.BOOT_COMPLETED" /> 
    </intent-filter> 
    <meta-data android:name="squrelabs.inspection" android:resource="@xml/wakeful" /> 
</receiver> 
</application> 

xml en ressources

<WakefulIntentService 
    listener="squrelabs.inspection.Droid.AppListener" 
/> 

bien vouloir me aider à résoudre ce problème.

Répondre

0

Problème lors de la lecture du fichier de métadonnées. eturn null lors de la lecture du fichier xml metadatafile dans BroadCastReceiver.

Vous pouvez ajouter l'attribut MetaData sur votre AlarmReceiver et modifier le code android:resource="@xml/wakeful" pour charger directement depuis la chaîne. Par exemple:

[MetaData("mTag", Value = "@string/WakefulIntentService")] 
ressource chaîne

est comme ceci:

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <string name="app_name">MetaDataDemo</string> 
    <string name="WakefulIntentService">squrelabs.inspection.Droid.AppListener </string> 

</resources> 

Ensuite, votre but final est d'obtenir le ((WakefulIntentService.IAlarmListener)cls.NewInstance()), vous pouvez remplacer le code:

 ActivityInfo activityInfo = packageManager.GetReceiverInfo(componentName, PackageInfoFlags.MetaData); 

     XmlReader reader = activityInfo.LoadXmlMetaData(packageManager, WAKEFUL_META_DATA); 

     while (reader!=null) 
     { 
      if (reader.IsStartElement()) 
      { 
       if (reader.Name == "WakefulIntentService") 
       { 
        string className = reader.Value; 
        Class cls = Java.Lang.Class.ForName(className); 
        return ((WakefulIntentService.IAlarmListener)cls.NewInstance()); 
       } 
      } 
      reader.MoveToNextAttribute(); 
     } 

Avec:

ComponentName cn = new ComponentName(context, Class); 
ActivityInfo info = context.PackageManager.GetReceiverInfo(cn, PackageInfoFlags.MetaData); 
System.String mTag = info.MetaData.GetString("mTag"); 
Class cls = Java.Lang.Class.ForName(mTag); 
return cls.NewInstance(); 

Mise à jour:

essayer de remplacer ce code avec var listener = ReflectionHelper.CreateInstance<WakefulIntentService.IAlarmListener>("Demo.AppListener", Assembly.GetExecutingAssembly().FullName); puis changer la chaîne WakefulIntentService comme ceci:

<string name="WakefulIntentService">yournamespace.AppListener</string>

Le ReflectionHelper est comme ceci:

public static class ReflectionHelper 
{ 

    public static T CreateInstance<T>(string fullName, string assemblyName) 
    { 
     string path = fullName + "," + assemblyName; 
     Type o = Type.GetType(path); 
     object obj = Activator.CreateInstance(o, true); 
     return (T)obj; 
    } 

    public static T CreateInstance<T>(string assemblyName, string nameSpace, string className) 
    { 
     try 
     { 
      string fullName = nameSpace + "." + className; 
      object ect = Assembly.Load(assemblyName).CreateInstance(fullName); 
      return (T)ect; 

     } 
     catch 
     { 
      return default(T); 
     } 
    } 
} 
+0

Merci. Essayons. –

+0

@SwapnilWakchaure, et essayez de supprimer le récepteur de votre manifeste et en attendant ajouter l'attribut 'IntentFilter' sur votre' AlarmReceiver', par exemple: '[BroadcastReceiver (Enabled = true)] [IntentFilter (new [] {" com .xamarin.example.TEST "})] [MetaData (" mTag ", Value =" @ chaîne/WakefulIntentService ")]' –

+0

Obtention ClassNotFoundException. En ligne Classe cls = Java.Lang.Class.ForName (mTag); –