JobService not running on Android Things - android-things

I try to work with JobScheduler and JobService on Android Things
My installation is RPI (Raspberry Pi) running IoT RPI3 1.0.2
this is my simple code:
package com.mystuff.jobservicetest;
import android.app.Activity;
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
JobScheduler jobScheduler = (JobScheduler) getSystemService(
Context.JOB_SCHEDULER_SERVICE);
ComponentName name = new ComponentName(this, JobServiceTest.class);
JobInfo jobInfo = new JobInfo.Builder(1,name).setPeriodic(1000).build();
int result = jobScheduler.schedule(jobInfo);
Log.d(TAG, "result = "+result);
}
public class JobServiceTest extends JobService {
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d(TAG, "Service job started");
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
return false;
}
}
}
AndroidManifest.xml looks simple like this:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mystuff.jobservicetest">
<application>
<uses-library android:name="com.google.android.things" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.IOT_LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<service android:name=".MainActivity$JobServiceTest"
android:permission="android.permission.BIND_JOB_SERVICE"/>
</application>
</manifest>
Outcome of logcat is just:
W/JobInfo: Specified interval for 1 is +1s0ms. Clamped to +15m0s0ms
Specified flex for 1 is +1s0ms. Clamped to +5m0s0ms
D/MainActivity: result = 1
I am missing "Service job started" log. Seems to onStartJob is never called.
Any hints?
Thanks

A JobService can only be scheduled in intervals of 15 minutes or longer. If you want a shorter task, you may want to look at alternative methods.

Related

Error Exception occurred while processing task when using Iap API from Amazon purchase

followed the instructions on amazon developer page to be able to add IAP API to my app. But it doesn't work and throws an error:
AbstractCommandTask: Exception occurred while processing task: com.amazon.a.a.n.a.a.a: AUTH_TOKEN_VERIFICATION_FAILURE: null: null
com.amazon.a.a.n.a.a.a: AUTH_TOKEN_VERIFICATION_FAILURE: null: null
at com.amazon.a.a.n.a.b.a(AuthenticationTokenVerifier.java:94)
at com.amazon.a.a.n.a.a.a(AbstractCommandTask.java:204)
at com.amazon.a.a.n.a.a.a(AbstractCommandTask.java:131)
at com.amazon.a.a.n.b.b$1.run(SimpleTaskPipeline.java:179)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.os.HandlerThread.run(HandlerThread.java:61)
I downloaded the amazon app tester and added the amazon.sdkteste.json file to the sdcard folder as shown in the instructions and in the app tester app also recognized this file.
I also downloaded the AppstoreAuthenticationKey.pem file and saved it to the app's app/src/main/assets folder. Can anyone tell me what am I missing or can someone give me a solution to fix this problem.
Thank
Below Is My AndroidManifest.xml Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.amazontinhtoannhanh">
<application
android:allowBackup="true"
android:dataExtractionRules="#xml/data_extraction_rules"
android:fullBackupContent="#xml/backup_rules"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.TinhToanNhanh"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name = "com.amazon.device.iap.ResponseReceiver"
android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY"
android:exported="true">
<intent-filter>
<action android:name = "com.amazon.inapp.purchasing.NOTIFY" />
</intent-filter>
</receiver>
</application>
</manifest>
MainActivity.java:
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import com.amazon.device.drm.LicensingService;
import com.amazon.device.iap.PurchasingService;
import java.util.HashSet;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
Button btn_subcire;
Set <String>productSkus=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LicensingService.verifyLicense(this.getApplicationContext(), new LicensingCallback());
TinhToanNhanhPurchasingLIstener purchasingListener= new TinhToanNhanhPurchasingLIstener();
PurchasingService.registerListener(this.getApplicationContext(), purchasingListener);
btn_subcire= (Button) findViewById(R.id.btn_subcire);
btn_subcire.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
PurchasingService.purchase("com.match.payment");
}
});
}
#Override
protected void onResume() {
super.onResume();
PurchasingService.getUserData();
productSkus = new HashSet<String>();
productSkus.add( "com.mathterm.payment" );
productSkus.add( "com.mathterm2.payment" );
productSkus.add( "com.mathterm3.payment" );
productSkus.add( "com.mathterm4.payment" );
productSkus.add("25");
PurchasingService.getProductData(productSkus);
PurchasingService.getPurchaseUpdates(false);
}
}
LicensingCallback.java:
import static android.content.ContentValues.TAG;
import android.util.Log;
import com.amazon.device.drm.model.LicenseResponse;
public class LicensingCallback implements com.amazon.device.drm.LicensingListener {
public void onLicenseCommandResponse(final LicenseResponse licenseResponse) {
final LicenseResponse.RequestStatus status = licenseResponse.getRequestStatus();
Log.d(TAG, "onLicenseCommandResponse: RequestStatus (" + status + ")");
switch (status) {
case LICENSED:
Log.d(TAG, "onLicenseCommandResponse: LICENSED");
break;
case NOT_LICENSED:
Log.d(TAG, "onLicenseCommandResponse: NOT_LICENSED");
break;
case ERROR_VERIFICATION:
Log.d(TAG, "onLicenseCommandResponse: ERROR_VERIFICATION");
break;
case ERROR_INVALID_LICENSING_KEYS:
Log.d(TAG, "onLicenseCommandResponse: ERROR_INVALID_LICENSING_KEYS");
break;
case EXPIRED:
Log.d(TAG, "onLicenseCommandResponse: EXPIRED");
break;
case UNKNOWN_ERROR:
Log.d(TAG, "onLicenseCommandResponse: ERROR");
} } }
TinhToanNhanhPurchasingLIstener:
import static android.content.ContentValues.TAG;
import android.util.Log;
import com.amazon.device.iap.PurchasingListener;
import com.amazon.device.iap.PurchasingService;
import com.amazon.device.iap.model.FulfillmentResult;
import com.amazon.device.iap.model.Product;
import com.amazon.device.iap.model.ProductDataResponse;
import com.amazon.device.iap.model.PurchaseResponse;
import com.amazon.device.iap.model.PurchaseUpdatesResponse;
import com.amazon.device.iap.model.Receipt;
import com.amazon.device.iap.model.UserDataResponse;
import java.util.Map;
public class TinhToanNhanhPurchasingLIstener implements PurchasingListener {
private String currentUserId = null ;
private String currentMarketplace = null ;
boolean reset = false ;
#Override
public void onUserDataResponse(UserDataResponse userDataResponse) {
final UserDataResponse.RequestStatus status = userDataResponse.getRequestStatus();
switch (status) {
case SUCCESSFUL:
currentUserId = userDataResponse.getUserData().getUserId();
currentMarketplace = userDataResponse.getUserData().getMarketplace();
break ;
case FAILED:
case NOT_SUPPORTED:
break ;
}
}
#Override
public void onProductDataResponse(ProductDataResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final String s : response.getUnavailableSkus()) {
Log.v(TAG, "Unavailable SKU:" + s);
}
final Map<String, Product> products = response.getProductData();
for ( final String key : products.keySet()) {
Product product = products.get(key);
Log.v(TAG, String.format( "Product: %s\n Type: %s\n SKU: %s\n Price: %s\n Description: %s\n" , product.getTitle(), product.getProductType(), product.getSku(), product.getPrice(), product.getDescription()));
}
break ;
case FAILED:
Log.v(TAG, "ProductDataRequestStatus: FAILED" );
break ;
}
}
#Override
public void onPurchaseResponse(PurchaseResponse purchaseResponse) {
switch (purchaseResponse.getRequestStatus())
{
case SUCCESSFUL:
PurchasingService. notifyFulfillment(purchaseResponse.getReceipt().getReceiptId(), FulfillmentResult.FULFILLED);
break;
case FAILED:
break;
}
}
#Override
public void onPurchaseUpdatesResponse(PurchaseUpdatesResponse response) {
switch (response.getRequestStatus()) {
case SUCCESSFUL:
for ( final Receipt receipt : response.getReceipts()) {
// Process receipts
}
if (response.hasMore()) {
PurchasingService.getPurchaseUpdates(true);
}
break ;
case FAILED:
break ;
}
}
}
I found the solution for it you just need to run the following adb command on the device where you want to run the app:
adb shell setprop debug.amazon.sandboxmode debug

Open android webview app when clicked on onesignal notification

Can somebody tell me what am I missing. I have a webview app. It works fine except this, when I close app onesignal notification arrives fine, but when I click notification app does not open. Here is some code related to this problem.
I have been searching for solution but what ever I have tried it does not work.
When app is running notification comes and opens fine, but when it is closed it wont start app.
Thanks.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OneSignal.startInit(this)
.inFocusDisplaying(OneSignal.OSInFocusDisplayOption.Notification)
.unsubscribeWhenNotificationsAreDisabled(true)
.setNotificationOpenedHandler(new
OneSignal.NotificationOpenedHandler() {
#Override
public void notificationOpened(OSNotificationOpenResult
result) {
String launchURL =
result.notification.payload.launchURL;
Intent intent = new Intent(getApplicationContext(),
NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT
| Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("url", launchURL);
startActivity(intent);
}
})
.init();
}
public class NotificationExtender extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult notification) {
OverrideSettings overrideSettings = new OverrideSettings();
overrideSettings.extender = new NotificationCompat.Extender() {
#Override
public NotificationCompat.Builder extend(NotificationCompat.Builder builder) {
// Sets the background notification color to Green on Android 5.0+ devices.
return builder.setColor(new BigInteger("#005aaa", 16).intValue())
.setSmallIcon(R.drawable.ic_stat_onesignal_default);
}
};
OSNotificationDisplayedResult displayedResult = displayNotification(overrideSettings);
Log.d("OneSignalExample", "Notification displayed with id: " + displayedResult.androidNotificationId);
return true;
}
}
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".NotificationExtender"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="false">
<intent-filter>
<action android:name="com.onesignal.NotificationExtender" />
</intent-filter>
</service>
<activity
android:name=".NotificationActivity"
android:parentActivityName=".MainActivity"/>
<meta-data android:name="com.onesignal.NotificationOpened.DEFAULT" android:value="DISABLE" />
I solved it.
It seams you do not need NotificationOpenedHandler, just NotificationExtender extends NotificationExtenderService. It look like this:
public class NotificationExtender extends NotificationExtenderService {
public NotificationExtender() {
super();
}
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
Intent intent = new Intent(getApplicationContext(), NotificationActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.putExtra("url", receivedResult.payload.launchURL);
PendingIntent pendingIntent = PendingIntent.getActivity(
getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT);
Uri uri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.ic_stat_onesignal_default)
.setSound(uri)
.setContentTitle(receivedResult.payload.title)
.setContentText(receivedResult.payload.body)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_onesignal_large_icon_default))
.setColor(getResources().getColor(R.color.logo_color))
.setAutoCancel(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
return true;
}
}

thymlead Error resolving template not found

I use thymlead for the first time. I would like to have header body and footer.
I'm getting exception whetever I try.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template "templates/layout", template might not exist or might not be accessible by any of the configured Template Resolvers
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:973)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
Here is my tiles configuration files :
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN"
"http://tiles.apache.org/dtds/tiles-config_2_0.dtd">
<tiles-definitions>
<definition name="base.definition" template="templates/layout">
<put-attribute name="title" value="" />
<put-attribute name="header" value="templates/header" />
<put-attribute name="menu" value="" />
<put-attribute name="body" value="templates/index" />
<put-attribute name="footer" value="templates/footer" />
</definition>
<definition name="index" extends="base.definition">
</definition>
</tiles-definitions>
This is my mvc configuration class.
package com.myproj.spring.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.thymeleaf.extras.tiles2.dialect.TilesDialect;
import org.thymeleaf.extras.tiles2.spring4.web.configurer.ThymeleafTilesConfigurer;
import org.thymeleaf.extras.tiles2.spring4.web.view.ThymeleafTilesView;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
#Configuration
#ComponentScan("com.myproj.spring")
#PropertySource("classpath:myproj.properties")
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**").addResourceLocations("/").setCachePeriod(31556926);
}
#Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver result = new ClassLoaderTemplateResolver();
result.setPrefix("/WEB-INF/views/");
result.setSuffix(".html");
result.setTemplateMode("HTML5");
result.setOrder(1);
return result;
}
#Bean
public ThymeleafTilesConfigurer tilesConfigurer() {
ThymeleafTilesConfigurer tilesConfigurer = new ThymeleafTilesConfigurer();
tilesConfigurer.setDefinitions(new String[] { "classpath:tiles/tiles-def.xml" });
return tilesConfigurer;
}
#Bean
public SpringTemplateEngine templateEngine(ClassLoaderTemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
templateEngine.addDialect(new TilesDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
viewResolver.setViewClass(ThymeleafTilesView.class);
return viewResolver;
}
}
and my controller
package com.myproj.spring.config;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#RequestMapping("/")
public class DefaultController {
#RequestMapping(value = { "/", "/home" }, method = RequestMethod.GET)
public String index(HttpServletRequest request) {
System.out.println("index page");
return "index";
}
#RequestMapping(value="/login", method = RequestMethod.GET)
public String login(HttpServletRequest request) {
System.out.println("login page");
return "login";
}
}
Here is my project structure
I'm using Spring Tools Suite and embedded Tomcat 8.
Any help please?
The solution is to put templates in src\main\resources.

Push Notifications Not Arriving

I am developing an android app using Xamarin and for push notifications I am using PushSharp.
I am having some trouble with receiving push notifications while the app is not running (after a reboot for example). Here is the Service code:
[BroadcastReceiver(Permission=GCMConstants.PERMISSION_GCM_INTENTS)]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_MESSAGE }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_REGISTRATION_CALLBACK }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new string[] { GCMConstants.INTENT_FROM_GCM_LIBRARY_RETRY }, Categories = new string[] { "com.xxx" })]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class PushHandlerBroadcastReceiver : PushHandlerBroadcastReceiverBase<PushHandlerService>
{
//IMPORTANT: Change this to your own Sender ID!
//The SENDER_ID is your Google API Console App Project ID.
// Be sure to get the right Project ID from your Google APIs Console. It's not the named project ID that appears in the Overview,
// but instead the numeric project id in the url: eg: https://code.google.com/apis/console/?pli=1#project:785671162406:overview
// where 785671162406 is the project id, which is the SENDER_ID to use!
public static string[] SENDER_IDS = new string[] {"1234"};
public const string TAG = "PushSharp-GCM";
}
And here is the appManifest that is created:
<receiver android:permission="com.google.android.c2dm.permission.SEND" android:name="xxx.PushHandlerBroadcastReceiver">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.xxx" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.xxx" />
</intent-filter>
<intent-filter>
<action android:name="com.google.android.gcm.intent.RETRY" />
<category android:name="com.xxx" />
</intent-filter>
</receiver>
<service android:name="xxx.PushHandlerService" />
My service code is very basic:
[Service] //Must use the service tag
public class PushHandlerService : PushHandlerServiceBase
{
public PushHandlerService () : base (PushHandlerBroadcastReceiver.SENDER_IDS)
{
}
protected override void OnRegistered (Context context, string registrationId)
{
...
}
protected override void OnUnRegistered (Context context, string registrationId)
{
...
}
protected override void OnMessage (Context context, Intent intent)
{
...
}
protected override bool OnRecoverableError (Context context, string errorId)
{
...
}
protected override void OnError (Context context, string errorId)
{
...
}
void createNotification (string title, string desc, Intent intent)
{
...
}
}
Am I missing something? why is the service not started once the phone is rebooted. Should I be doing something in the broadcast receiver? Should I register to the push notifications in the service constructor (to handle the case where the app is not started yet)?
If your service does not start on reboot you can add a BroadcastReceiver to your project which starts it:
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
public class MyBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
MyNotificationService.RunIntentInService(context, intent);
SetResult(Result.Ok, null, null);
}
}
If you are using PushSharp you can probably get away with adding that filter to the PushHandlerBroadcastReceiverBase implementation.

How can i remove namespace from the generated JAXB File?

Here is my code:
xsdFile:
<complexType name="Player">
<sequence>
<element name="Login" type="string"></element>
<element name="Passwd" type="string"></element>
</sequence>
</complexType>
<element name="Player" type="tns:Player"></element>
Build.xml:
<exec executable="${javahome}/bin/xjc" >
<arg value="-extension" />
<arg value="-b" />
<arg value="binding.xml" />
<arg value="-d" />
<arg value="${sources}" />
<arg value="-p" />
<arg value="metier" />
<arg value="Player.xsd" />
</exec>
</target>
binding.xml:
<jxb:bindings
xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" elementFormDefault="qualified" attributeFormDefault="unqualified"
version="2.1">
<jxb:globalBindings>
<xjc:simple />
<xjc:serializable/>
</jxb:globalBindings>
And finnaly:
JAXBContext context = JAXBContext.newInstance(Player.class,ObjectFactory.class);
Unmarshaller decodeur = context.createUnmarshaller();
i add "xjc:simple" in order to have #XMLRootElement, but an exception is raised: javax.xml.bind.UnmarshalException: unexpected element (uri:"http://www.example.org/Player"
It didn't work correctly because i got this:#XmlRootElement(name = "Player", namespace = "http://www.example.org/Player")
Instead of just: #XmlRootElement(name = "Player")
How can i remove this "namespace" ?
Thanks
If your XML schema indicates that the corresponding XML documents should be namespace qualified, then JAXB will generate a Java model with the expected namespace qualification. Below I'll describe a way in which you could leverage a StAX parser to fool JAXB into thinking it is parsing a namespace qualfied document:
Player
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement(name="Player", namespace="http://www.example.org/Player")
public class Player {
private String login;
private String passwd;
#XmlElement(name="Login", namespace="http://www.example.org/Player")
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
#XmlElement(name="Passwd", namespace="http://www.example.org/Player")
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
}
NamespaceDelegate
We will create an implementation of StreamReaderDelegate. This delegate will report the namespace for all element events to be "http://www.example.org/Player". Note: This trick assumes that all your elements are qualified with the same namespace URI.
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class NamespaceDelegate extends StreamReaderDelegate {
private static String NAMESPACE = "http://www.example.org/Player";
public NamespaceDelegate(XMLStreamReader xsr) {
super(xsr);
}
#Override
public String getNamespaceURI() {
return NAMESPACE;
}
}
Demo
import java.io.FileInputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.util.StreamReaderDelegate;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Player.class);
FileInputStream xmlStream = new FileInputStream("input.xml");
XMLInputFactory xif = XMLInputFactory.newFactory();
XMLStreamReader xsr = xif.createXMLStreamReader(xmlStream);
StreamReaderDelegate srd = new NamespaceDelegate(xsr);
Unmarshaller unmarshaller = jc.createUnmarshaller();
Player player = (Player) unmarshaller.unmarshal(srd);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(player, System.out);
}
}
input.xml
<?xml version="1.0" encoding="UTF-8"?>
<Player>
<Login>FOO</Login>
<Passwd>BAR</Passwd>
</Player>
I just delete "ObjectFactory.class" and it works.
New code:
JAXBContext context = JAXBContext.newInstance(Player.class);
Unmarshaller decodeur = context.createUnmarshaller();

Resources