在xamarin.android中实现weakfulIntentService。 读取元数据文件时出现问题 在BroadCastReceiver中读取metadatafile xml文件时输出null。
** XmlReader reader = activityInfo.LoadXmlMetaData(packageManager,WAKEFUL_META_DATA); **
广播接收器
SELECT * from holidays JOIN holiday_info ON holidays.holiday_id = holiday_info.holiday_id
清单
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);
}
}
资源中的xml
<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>
请帮助我解决这个问题。
答案 0 :(得分:0)
读取元数据文件时出现问题。在BroadCastReceiver中读取metadatafile xml文件时输出null。
您可以在MetaData
上添加属性AlarmReceiver
,并更改android:resource="@xml/wakeful"
代码以直接从字符串加载资源。例如:
[MetaData("mTag", Value = "@string/WakefulIntentService")]
字符串资源是这样的:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MetaDataDemo</string>
<string name="WakefulIntentService">squrelabs.inspection.Droid.AppListener </string>
</resources>
然后你的最终目的是获得((WakefulIntentService.IAlarmListener)cls.NewInstance())
,你可以替换代码:
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();
}
使用:
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();
更新
尝试用var listener = ReflectionHelper.CreateInstance<WakefulIntentService.IAlarmListener>("Demo.AppListener", Assembly.GetExecutingAssembly().FullName);
替换此代码,然后像这样更改字符串WakefulIntentService
:
<string name="WakefulIntentService">yournamespace.AppListener</string>
ReflectionHelper
是这样的:
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);
}
}
}