I know there are those questions which are similar to mine have already raised.
However, I can not go further more on some point.
** I can not copy file on below.-> realm.writeCopyTo(exportRealmFile);
** The code that I referred to is below.
https://stackoverflow.com/a/36324183/6650123
And let me share my application class which I defaulted Realm.
Wondering if the realm file can not be copied because of that..
Would you take a look and advise?
**
public class MyApplication extends Application {
private static MyApplication singleton;
private RealmConfiguration realmConfig;
String TAG=getClass().getName();
public static MyApplication getSingleton(){;
return singleton;
}
public void onCreate() {
super.onCreate();
singleton=this;
// Create the Realm configuration
realmConfig = new RealmConfiguration.Builder(this).build();
Realm.setDefaultConfiguration(realmConfig);
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
public void onLowMemory() {
super.onLowMemory();
}
public void onTerminate() {
super.onTerminate();
}
}
// my codes for backup realm
package com.first.project;
import android.content.Context;
import android.os.Environment;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import io.realm.Realm;
public class RealmBackupRestore {
private final static String TAG = RealmBackupRestore.class.getName();
private Context context;
private Realm realm;
public RealmBackupRestore(Context context) {
realm= Realm.getDefaultInstance();
//this.realm = Realm.getInstance(BaseApplication.realmConfiguration);
this.context = context;
}
public void backup() {
Log.d(TAG, "realm은"+realm);
Log.d(TAG, "Realm.getDefaultInstance();은"+Realm.getDefaultInstance());
File exportRealmFile = null;
File exportRealmPATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Log.d(TAG, "exportRealmPATH"+exportRealmPATH);
String exportRealmFileName = "aa.realm";
Log.d(TAG, "Realm DB Path = " + realm.getPath());
try {
// create a backup file
exportRealmFile = new File(exportRealmPATH, exportRealmFileName);
// if backup file already exists, delete it
exportRealmFile.delete();
// copy current realm to backup file
realm.writeCopyTo(exportRealmFile);
} catch (IOException e) {
e.printStackTrace();
}
String msg = "File exported to Path: " +Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Log.d(TAG, msg);
realm.close();
}
public void restore() {
//Restore
File exportRealmPATH = context.getExternalFilesDir(null);
String FileName = "default.realm";
String restoreFilePath = context.getExternalFilesDir(null) + "/" + FileName;
Log.d(TAG, "oldFilePath = " + restoreFilePath);
copyBundledRealmFile(restoreFilePath, FileName);
Log.d(TAG, "Data restore is done");
}
private String copyBundledRealmFile(String oldFilePath, String outFileName) {
try {
File file = new File(context.getFilesDir(), outFileName);
Log.d(TAG, "context.getFilesDir() = " + context.getFilesDir().toString());
FileOutputStream outputStream = new FileOutputStream(file);
FileInputStream inputStream = new FileInputStream(new File(oldFilePath));
byte[] buf = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buf)) > 0) {
outputStream.write(buf, 0, bytesRead);
}
outputStream.close();
return file.getAbsolutePath();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private String dbPath() {
return realm.getPath();
}
}
Related
So I am creating a route planner app in Android Studio and its giving me the error in the title of this question
Heres my code
import android.Manifest;
import android.app.Fragment;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.example.destinationrouteplanner.R;
import com.example.destinationrouteplanner.adapters.UserRecyclerAdapter;
import com.example.destinationrouteplanner.models.MarkerCluster;
import com.example.destinationrouteplanner.models.User;
import com.example.destinationrouteplanner.util.MyClusterManagerRenderer;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.maps.android.clustering.ClusterManager;
import java.util.ArrayList;
public class UserListFragment extends Fragment implements OnMapReadyCallback
{
private static final String TAG = "UserListFragment";
private RecyclerView mUserListRecyclerView;
private MapView mMapView;
private ArrayList<User> mUserList = new ArrayList<>();
//private UserRecyclerAdapter mUserRecyclerAdapter;
private ArrayList<UserLocation> mUserLocations = new ArrayList<>();
private UserRecyclerAdapter mUserRecyclerAdapter;
private GoogleMap mGoogleMap;
private LatLngBounds mMapBoundary;
private UserLocation mUserPosition;
private ClusterManager mClusterManager;
private MyClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<MarkerCluster> mClusterMarkers = new ArrayList<>();
public static UserListFragment newInstance() {
return new UserListFragment();
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mUserList = getArguments().getParcelableArrayList(getString(R.string.intent_user_list));
}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_user_list, container, false);
mUserListRecyclerView = view.findViewById(R.id.user_list_recycler_view);
mMapView = view.findViewById(R.id.user_list_map);
initUserListRecyclerView();
initGoogleMap(savedInstanceState);
return view;
}
private void initGoogleMap(Bundle savedInstanceState){
// *** IMPORTANT ***
// MapView requires that the Bundle you pass contain _ONLY_ MapView SDK
// objects or sub-Bundles.
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY);
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
}
private void initUserListRecyclerView() {
mUserRecyclerAdapter = new UserRecyclerAdapter(mUserList);
mUserListRecyclerView.setAdapter(mUserRecyclerAdapter);
mUserListRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE_KEY);
if (mapViewBundle == null) {
mapViewBundle = new Bundle();
outState.putBundle(MAPVIEW_BUNDLE_KEY, mapViewBundle);
}
mMapView.onSaveInstanceState(mapViewBundle);
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onStart() {
super.onStart();
mMapView.onStart();
}
#Override
public void onStop() {
super.onStop();
mMapView.onStop();
}
#Override
public void onMapReady(GoogleMap map) {
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
map.setMyLocationEnabled(true);
mGoogleMap = map;
addMapMarkers();
}
#Override
public void onPause() {
mMapView.onPause();
super.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
private void addMapMarkers()
{
if (mGoogleMap !=null)
{
if(mClusterManager == null)
{
mClusterManager = new ClusterManager<MarkerCluster>(getActivity().getApplicationContext(), mGoogleMap);
}
if (mClusterManagerRenderer == null)
{
mClusterManagerRenderer = new MyClusterManagerRenderer(getActivity(), mGoogleMap, mClusterManager);
mClusterManager.setRenderer(mClusterManagerRenderer);
}
for (UserLocation userLocation: mUserLocations)
{
Log.d(TAG, "AddMapMarkers: location: " + userLocation.getGeo_point().toString());
try {
String snippet = "";
if (userLocation.getUser().getUser_id().equals(FirebaseAuth.getInstance().getUid()))
{
snippet = "This is you";
}else {
snippet = "Determine route to " + userLocation.getUser().getUsername() + "?";
}
int avatar = R.drawable.cwm_logo; //Set the default avatar
try {
avatar = Integer.parseInt(userLocation.getUser().getAvatar());
}catch (NumberFormatException e)
{
Log.d(TAG, "addMapMarkers: no avatar for: " + userLocation.getUser().getUsername() + ", setting default");
}
MarkerCluster newMarkerCluster = new MarkerCluster(new LatLng(userLocation.getGeo_point().getLatitude(), userLocation.getGeo_point().getLongitude(), userLocation.getUser().getUsername(), snippet, avatar, userLocation.getUser()));
mClusterManager.addItem(newMarkerCluster);
mClusterMarkers.add(newMarkerCluster);
}catch (NullPointerException e)
{
Log.e(TAG "addMapMarkers: NullPointerException: " + e.getMessage());
}
}
mClusterManager.cluster();
setCameraView();
}
}
private void setCameraView()
{
double bottomBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double leftBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
double topBoundary = mUserPosition.getGeo_point().getLatitude() - .1;
double rightBoundary = mUserPosition.getGeo_point().getLongitude() - .1;
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
}
}
I tired using the answer to this question but not working
Required type:
ArrayList
Provided:
ArrayList
no instance(s) of type variable(s) exist so that UserLocation conforms to Object
I'm walking through a pivotal 'guide' project, my first time uploading files in Spring.
I've implemented the code exactly as the guide specifies but still am getting the following error:
Parameter 0 of constructor in hello.storage.FileSystemStorageService required a bean of type 'hello.storage.StorageProperties' that could not be found.
Consider defining a bean of type 'hello.storage.StorageProperties' in your configuration.
I've reviewed many so posts and it seems the common thread is to move my 'application' class to the root package, but its already there. Here is my project:
UploadingFiles1Application.java
package hello;
// multiple imports
#SpringBootApplication
public class UploadingFiles1Application {
public static void main(String[] args) {
SpringApplication.run(UploadingFiles1Application.class, args);
}
#Bean
CommandLineRunner init(StorageService storageService) {
return (args) -> {
storageService.deleteAll();
storageService.init();
};
}
}
And here's my Service:
package hello.storage;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.nio.file.Path;
import java.util.stream.Stream;
public interface StorageService {
void init();
void store(MultipartFile file);
Stream<Path> loadAll();
Path load(String filename);
Resource loadAsResource(String filename);
void deleteAll();
}
And its implementation:
package hello.storage;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.stream.Stream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
#Service
public class FileSystemStorageService implements StorageService {
private final Path rootLocation;
#Autowired
public FileSystemStorageService(StorageProperties properties) {
this.rootLocation = Paths.get(properties.getLocation());
}
#Override
public void store(MultipartFile file) {
String filename = StringUtils.cleanPath(file.getOriginalFilename());
try {
if (file.isEmpty()) {
throw new StorageException("Failed to store empty file " + filename);
}
if (filename.contains("..")) {
// This is a security check
throw new StorageException(
"Cannot store file with relative path outside current directory "
+ filename);
}
try (InputStream inputStream = file.getInputStream()) {
Files.copy(inputStream, this.rootLocation.resolve(filename),
StandardCopyOption.REPLACE_EXISTING);
}
}
catch (IOException e) {
throw new StorageException("Failed to store file " + filename, e);
}
}
#Override
public Stream<Path> loadAll() {
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(this.rootLocation::relativize);
}
catch (IOException e) {
throw new StorageException("Failed to read stored files", e);
}
}
#Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
#Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if (resource.exists() || resource.isReadable()) {
return resource;
}
else {
throw new StorageFileNotFoundException(
"Could not read file: " + filename);
}
}
catch (MalformedURLException e) {
throw new StorageFileNotFoundException("Could not read file: " + filename, e);
}
}
#Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
#Override
public void init() {
try {
Files.createDirectories(rootLocation);
}
catch (IOException e) {
throw new StorageException("Could not initialize storage", e);
}
}
}
What am I missing??
Thanks in advance.
First of all i do not know if your StorageProperties is a spring component or just a simple java class!
I am going to suppose that it is a spring component :
#Component
public class StorageProperties {
...
}
In the FileSystemStorageService, you replace the constructor by a postConstruct method :
#Service
public class FileSystemStorageService implements StorageService {
private Path rootLocation;
#Autowired
StorageProperties properties;
#PostConstruct
public void FileSystemStorageService() {
this.rootLocation = Paths.get(properties.getLocation());
....
}
package com.email.test;
import java.util.Arrays;
import java.util.Properties;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.Flags.Flag;
import javax.mail.Folder;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Store;
import javax.mail.search.FlagTerm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public abstract class SampleEmailReader {
public static final int SUCCESS = 0;
public static final int FAILURE = -1;
private transient static final Logger logger = LoggerFactory.getLogger(SampleEmailReader.class);
public SampleEmailReader() {
}
public void processEmailAttachements() {
try {
logger.info("Started processEmailAttachements ");
Properties emailProperties = new Properties();
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
emailProperties.setProperty("mail.imaps.socketFactory.class", SSL_FACTORY);
emailProperties.setProperty("mail.imaps.socketFactory.fallback", "false");
emailProperties.setProperty("mail.imaps.port", "993");
emailProperties.setProperty("mail.imaps.socketFactory.port", "993");
emailProperties.setProperty("mail.imaps.auth", "true");
emailProperties.setProperty("mail.imaps.host", "outlook.office365.com");
emailProperties.setProperty("mail.imaps.auth.plain.disable", "true");
emailProperties.setProperty("mail.imaps.auth.gssapi.disable", "true");
emailProperties.setProperty("mail.imaps.auth.ntlm.disable", "true");
emailProperties.setProperty("mail.imaps.ssl.enable", "true");
Session session = Session.getInstance(emailProperties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("test#outlook.com", "password#2016");
}
});
Store store = session.getStore("imaps");
store.connect();
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_WRITE);
logger.info("Inbox MessageCount-->" + inbox.getMessageCount());
Message messages[] = inbox.search(new FlagTerm(
new Flags(Flag.SEEN), false));
logger.info("Number of UnRead Mails = " + messages.length);
for (Message inboxMessage : messages) {
int status = processMessageBody(inboxMessage);
if (status == SUCCESS) {
inboxMessage.setFlag(Flag.SEEN, true);
} else {
inboxMessage.setFlag(Flag.SEEN, false);
}
}
inbox.close(true);
store.close();
} catch (Exception ex) {
ex.printStackTrace();
logger.error("Error in processEmailAttachements", ex);
}
}
private int processMessageBody(Message message) {
int status = FAILURE;
try {
logger.info("Started processMessageBody*******");
logger.info("Message Subject******" + message.getSubject());
logger.info("From Address *******"
+ Arrays.toString(message.getFrom()));
Object content = message.getContent();
if (content instanceof String) {
logger.error("Invalid Content Type.No need to process the Mail with Subject "
+ message.getSubject());
} else if (content instanceof Multipart) {
Multipart multiPart = (Multipart) content;
try {
for (int i = 0; i < multiPart.getCount(); i++) {
BodyPart bodyPart = multiPart.getBodyPart(i);
if (bodyPart.getDisposition() != null
&& bodyPart.getDisposition().equalsIgnoreCase(
Part.ATTACHMENT)
&& bodyPart.getFileName() != null) {
status = readExcel(bodyPart);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("BatchException in procesMultiPart", e);
}
}
} catch (Exception e) {
e.printStackTrace();
logger.error("Exception in processMessageBody", e);
}
return status;
}
public abstract int readExcel(BodyPart bodyPart);
}
Executing
package EmailTable;
import javax.mail.BodyPart;
public class Email {
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleEmailReader reader = new SampleEmailReader() {
#Override
public int readExcel(BodyPart bodyPart) {
// TODO Auto-generated method stub
return 0;
}
};
reader.processEmailAttachements();
}
}
Getting Autheticate Failed.. But username password is correct. and i am able to login outlook 365 with the username and password. ONLY difference I am seeing there is certitificate displayed on the browser.. Do I need to use any certificate to read the mail?
javax.mail.AuthenticationFailedException: LOGIN failed.
at com.sun.mail.imap.IMAPStore.protocolConnect
I have created a writer for BucketingSink. The sink and writer works without error but when it comes to the writer writing avro genericrecord to parquet, the file was created from in-progress, pending to complete. But the files are empty with 0 bytes. Can anyone tell me what is wrong with the code ? I have tried placing the initialization of AvroParquetWriter at the open() method, but result still the same.
When debugging the code, I confirm that writer.write(element) does executed and element contain the avro genericrecord data
Streaming Data
BucketingSink<DataEventRecord> sink =
new BucketingSink<DataEventRecord>("hdfs://localhost:9000/tmp/");
sink.setBucketer(new DateTimeBucketer<DataEventRecord>("yyyy-MM-dd--HHmm"));
sink.setWriter(new ParquetSinkWriter<DataEventRecord>());
ParquetSinkWriter
import java.io.File;
import java.io.IOException;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericRecord;
import org.apache.flink.streaming.connectors.fs.StreamWriterBase;
import org.apache.flink.streaming.connectors.fs.Writer;
import org.apache.parquet.avro.AvroParquetWriter;
import org.apache.parquet.hadoop.ParquetWriter;
import org.apache.parquet.hadoop.metadata.CompressionCodecName;
import com.any.DataEventRecord;
public class ParquetSinkWriter<T> extends StreamWriterBase<T> {
private transient ParquetWriter<GenericRecord> writer;
private Path path;
private FileSystem fs;
private final CompressionCodecName compressionCodecName = CompressionCodecName.SNAPPY;
private final int blockSize = 256 * 1024 * 1024;
private final int pageSize = 64 * 1024;
#Override
// workaround
public void open(FileSystem fs, Path path) throws IOException {
super.open(fs, path);
this.path = path;
this.fs = fs;
}
#Override
public void write(T event) throws IOException {
DataEventRecord element = (DataEventRecord) event;
if (writer == null) {
writer = new AvroParquetWriter<GenericRecord>(this.path, element.getSchema(), compressionCodecName, blockSize, pageSize);
}
if (writer != null) {
GenericRecord datum = element.getRecord();
writer.write(datum);
}
}
#Override
public void close() throws IOException {
if (writer != null) {
writer.close();
}
super.close();
}
#Override
public Writer<T> duplicate() {
return new ParquetSinkWriter<T>();
}
}
Directly implementing Writer should look like
import org.apache.flink.util.Preconditions;
import org.apache.avro.Schema;
import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericRecord;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.parquet.avro.AvroParquetWriter;
import org.apache.parquet.hadoop.ParquetWriter;
import org.apache.parquet.hadoop.metadata.CompressionCodecName;
import java.io.IOException;
/**
* Parquet writer.
*
* #param <T>
*/
public class ParquetSinkWriter<T extends GenericRecord> implements Writer<T> {
private static final long serialVersionUID = -975302556515811398L;
private final CompressionCodecName compressionCodecName = CompressionCodecName.SNAPPY;
private final int pageSize = 64 * 1024;
private final String schemaRepresentation;
private transient Schema schema;
private transient ParquetWriter<GenericRecord> writer;
private transient Path path;
private int position;
public ParquetSinkWriter(String schemaRepresentation) {
this.schemaRepresentation = Preconditions.checkNotNull(schemaRepresentation);
}
#Override
public void open(FileSystem fs, Path path) throws IOException {
this.position = 0;
this.path = path;
if (writer != null) {
writer.close();
}
writer = createWriter();
}
#Override
public long flush() throws IOException {
Preconditions.checkNotNull(writer);
position += writer.getDataSize();
writer.close();
writer = createWriter();
return position;
}
#Override
public long getPos() throws IOException {
Preconditions.checkNotNull(writer);
return position + writer.getDataSize();
}
#Override
public void close() throws IOException {
if (writer != null) {
writer.close();
writer = null;
}
}
#Override
public void write(T element) throws IOException {
Preconditions.checkNotNull(writer);
writer.write(element);
}
#Override
public Writer<T> duplicate() {
return new ParquetSinkWriter<>(schemaRepresentation);
}
private ParquetWriter<GenericRecord> createWriter() throws IOException {
if (schema == null) {
schema = new Schema.Parser().parse(schemaRepresentation);
}
return AvroParquetWriter.<GenericRecord>builder(path)
.withSchema(schema)
.withDataModel(new GenericData())
.withCompressionCodec(compressionCodecName)
.withPageSize(pageSize)
.build();
}
}
I followed a tutorial on how to write a NDEF message to a tag. and now when I run it. it detects the tag and when I press the button to write the message and the app crashes. it gives me JAVA.LANG.ArrayIndexOutOfBoundsException can someone please help me on what I'm doing wrong.
this is the error I see in logcat.
any help is appreciated.
Here is the code:
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class WriteMessage extends Activity {
NfcAdapter adapter;
PendingIntent pendingIntent;
IntentFilter writeTagFilters[];
boolean writeMode;
Tag myTag;
Context ctx;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_write_message);
ctx=this;
Button WriteTag = (Button) findViewById (R.id.WriteTag);
final TextView Message = (TextView) findViewById (R.id.MessageBox);
WriteTag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try{
if(myTag==null){
Toast.makeText(ctx, "Error_detected", Toast.LENGTH_LONG).show();
}else{
write(Message.getText().toString(), myTag);
Toast.makeText(ctx, "Ok_Writing", Toast.LENGTH_LONG).show();
}
}catch(IOException e){
Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
e.printStackTrace();
//} catch(FormatException e){
e.printStackTrace();
} catch (FormatException e) {
// TODO Auto-generated catch block
Toast.makeText(ctx, "Error_Writing", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
});
adapter = NfcAdapter.getDefaultAdapter(this);
pendingIntent = PendingIntent.getActivity(this, 0, new Intent (this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter (NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[] {tagDetected };
}
private void write(String text, Tag myTag)throws IOException, FormatException {
NdefRecord[] records = {createRecord(text)};
NdefMessage message = new NdefMessage(records);
Ndef ndef = Ndef.get(myTag);
ndef.connect();
ndef.writeNdefMessage(message);
ndef.close();
}
private NdefRecord createRecord (String text ) throws UnsupportedEncodingException {
String lang = "en";
byte[] textBytes = text.getBytes();
byte[] langBytes = lang.getBytes("US-ASCII");
int langLength = langBytes.length;
int textLength = textBytes.length;
byte[] payload = new byte [1+ langLength + textLength ];
payload[0] = (byte) langLength;
System.arraycopy(langBytes, 0, payload, 1, langLength);
System.arraycopy(langBytes, 0, payload, 1 + langLength, textLength);
NdefRecord recordNFC = new NdefRecord (NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);
return recordNFC;
}
#Override
protected void onNewIntent(Intent intent){
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Toast.makeText(this, "ok_detection" + myTag.toString(), Toast.LENGTH_LONG ).show();
}
}
#Override
public void onPause(){
super.onPause();
WriteModeOff();
}
#Override
public void onResume(){
super.onResume();
WriteModeOn();
}
private void WriteModeOn(){
writeMode = true;
adapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}
private void WriteModeOff(){
writeMode = false;
adapter.disableForegroundDispatch(this);
}
}
Looks like createRecord() is copying langBytes into payload twice instead of copying textBytes, but with the length of textBytes. If textBytes is longer than langBytes, it won't find enough data to copy from the source.
See the documentation on arraycopy.