I am creating realtime andoid chat app in java, backend in nodejs and mongodb.
I want to ask
How to save chat in mongodb?
How to upload lager files in nodejs or mongodb? I cann't upload file more than 100kb in this.
this is the code.
ChatActivity.java
package com.example.chat;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Base64;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
public class ChatActivity extends AppCompatActivity implements TextWatcher {
AdView mAdView;
private String name;
private WebSocket webSocket;
private String SERVER_PATH = "ws://group2all.com:50000/";
private EditText messageEdit;
private View sendBtn, pickImgBtn;
private RecyclerView recyclerView;
private int IMAGE_REQUEST_ID = 1;
private MessageAdapter messageAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
MobileAds.initialize(this, new OnInitializationCompleteListener() {
#Override
public void onInitializationComplete(InitializationStatus initializationStatus) {
}
});
mAdView = findViewById(R.id.adView4);
AdRequest adRequest = new AdRequest.Builder().build();
mAdView.loadAd(adRequest);
name = getIntent().getStringExtra("name");
initiateSocketConnection();
}
private void initiateSocketConnection() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(SERVER_PATH).build();
webSocket = client.newWebSocket(request, new SocketListener());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
String string = s.toString().trim();
if (string.isEmpty()) {
resetMessageEdit();
} else {
sendBtn.setVisibility(View.VISIBLE);
pickImgBtn.setVisibility(View.INVISIBLE);
}
}
private void resetMessageEdit() {
messageEdit.removeTextChangedListener(this);
messageEdit.setText("");
sendBtn.setVisibility(View.INVISIBLE);
pickImgBtn.setVisibility(View.VISIBLE);
messageEdit.addTextChangedListener(this);
}
private class SocketListener extends WebSocketListener {
#Override
public void onOpen(WebSocket webSocket, Response response) {
super.onOpen(webSocket, response);
runOnUiThread(() -> {
Toast.makeText(ChatActivity.this,
"Socket Connection Successful!",
Toast.LENGTH_SHORT).show();
initializeView();
});
}
#Override
public void onMessage(WebSocket webSocket, String text) {
super.onMessage(webSocket, text);
runOnUiThread(() -> {
try {
JSONObject jsonObject = new JSONObject(text);
jsonObject.put("isSent", false);
messageAdapter.addItem(jsonObject);
recyclerView.smoothScrollToPosition(messageAdapter.getItemCount() - 1);
} catch (JSONException e) {
e.printStackTrace();
}
});
}
}
private void initializeView() {
messageEdit = findViewById(R.id.messageEdit);
sendBtn = findViewById(R.id.sendBtn);
pickImgBtn = findViewById(R.id.pickImgBtn);
recyclerView = findViewById(R.id.recyclerView);
messageAdapter = new MessageAdapter(getLayoutInflater());
recyclerView.setAdapter(messageAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
messageEdit.addTextChangedListener(this);
sendBtn.setOnClickListener(v -> {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("name", name);
jsonObject.put("message", messageEdit.getText().toString());
webSocket.send(jsonObject.toString());
jsonObject.put("isSent", true);
messageAdapter.addItem(jsonObject);
recyclerView.smoothScrollToPosition(messageAdapter.getItemCount() - 1);
resetMessageEdit();
} catch (JSONException e) {
e.printStackTrace();
}
});
pickImgBtn.setOnClickListener(v -> {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
intent.setType("video/*");
startActivityForResult(Intent.createChooser(intent, "Pick image"),
IMAGE_REQUEST_ID);
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == IMAGE_REQUEST_ID && resultCode == RESULT_OK) {
try {
InputStream is = getContentResolver().openInputStream(data.getData());
Bitmap image = BitmapFactory.decodeStream(is);
sendImage(image);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
private void sendImage(Bitmap image) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
String base64String = Base64.encodeToString(outputStream.toByteArray(),
Base64.DEFAULT);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("name", name);
jsonObject.put("image", base64String);
webSocket.send(jsonObject.toString());
jsonObject.put("isSent", true);
messageAdapter.addItem(jsonObject);
recyclerView.smoothScrollToPosition(messageAdapter.getItemCount() - 1);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
This is server.js file
const SocketServer = require('websocket').server
const http = require('http')
const express = require('express')
const app = express()
const mongoClient = require('mongodb').MongoClient
const server = http.createServer((req, res) => {})
const url = "mongodb://localhost:27017"
server.listen(50000, ()=>{
console.log("Listening on port 50000...")
})
app.listen(60000, () => {
console.log("Listening on port 60000...")
})
app.use(express.json())
mongoClient.connect(url, (err, db) => {
if (err) {
console.log("Error while connecting mongo client")
} else {
const myDb = db.db('myDb')
const collection = myDb.collection('myTable')
app.post('/signup', (req, res) => {
const newUser = {
name: req.body.name,
email: req.body.email,
password: req.body.password
}
const query = { email: newUser.email }
collection.findOne(query, (err, result) => {
if (result == null) {
collection.insertOne(newUser, (err, result) => {
res.status(200).send()
})
} else {
res.status(400).send()
}
})
})
app.post('/login', (req, res) => {
const query = {
email: req.body.email,
password: req.body.password
}
collection.findOne(query, (err, result) => {
if (result != null) {
const objToSend = {
name: result.name,
email: result.email
}
res.status(200).send(JSON.stringify(objToSend))
} else {
res.status(404).send()
}
})
})
}
})
wsServer = new SocketServer({httpServer:server})
const connections = []
wsServer.on('request', (req) => {
const connection = req.accept()
console.log('new connection')
connections.push(connection)
connection.on('message', (mes) => {
connections.forEach(element => {
if (element != connection)
element.sendUTF(mes.utf8Data)
})
})
connection.on('close', (resCode, des) => {
console.log('connection closed')
connections.splice(connections.indexOf(connection), 1)
})
})
One more thing i want to ask in js file
Can i use one port in this at 60000?If yes how?
Please tell me code to better understanding.
Related
I am newbie to flutter and java.
I am trying to send a stream of data from speechRecognizer.recognized.addeventlistener function from java to flutter. speechRecognizer.recognized.addeventlistener is using Microsoft Azure speech to text API .But the sink.success, attachEvent.success in my case is not sending any string to flutter.
I have attached a main.dart, homepage.dart code as well as java code here.
Hope you guys will help me to find a solution.
For safety reasons, I have removed YourSubscriptionKey and YourServiceRegion.
main.dart
import 'package:flutter/material.dart';
import 'home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Event Channel Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Demo page'),
);
}
}
home_page.dart
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
static const stream = EventChannel(
'com.chamelalaboratory.demo.flutter_event_channel/eventChannel');
late StreamSubscription _streamSubscription;
String _currentValue = "";
void _startListener() {
_streamSubscription = stream.receiveBroadcastStream().listen(_listenStream);
}
void _cancelListener() {
_streamSubscription.cancel();
setState(() {
_currentValue = "Start Recording...";
});
}
void _listenStream(value) {
debugPrint("Received From Native: $value\n");
setState(() {
_currentValue = value;
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(_currentValue.toUpperCase(), textAlign: TextAlign.justify),
const SizedBox(
height: 50,
),
//Start Btn
ElevatedButton(
onPressed: () => _startListener(),
child: Text("Record".toUpperCase()),
),
const SizedBox(
height: 50,
),
//Cancel Btn
ElevatedButton(
onPressed: () => _cancelListener(),
child: Text("Stop".toUpperCase()),
),
],
),
),
);
}
}
MainActivity.java
package com.example.sounddiaryapp;
import androidx.annotation.NonNull;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
import com.microsoft.cognitiveservices.speech.*;
import com.microsoft.cognitiveservices.speech.audio.*;
import java.util.concurrent.ExecutionException;
import java.io.IOException;
import java.util.concurrent.Future;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.util.*;
import java.util.concurrent.Future;
import static android.Manifest.permission.*;
import java.util.concurrent.TimeUnit;
import android.os.Handler;
import java.util.Objects;
import io.flutter.plugin.common.EventChannel;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "codecommon";
private static String YourSubscriptionKey = "";
private static String YourServiceRegion = "";
public static final String STREAM = "com.chamelalaboratory.demo.flutter_event_channel/eventChannel";
final String TAG_NAME = "From_Native";
private EventChannel.EventSink attachEvent;
private int count = 1;
public String receivedText = "";
List<String> textList=new ArrayList<String>();
private Handler handler;
SpeechConfig speechConfig = SpeechConfig.fromSubscription(YourSubscriptionKey,
YourServiceRegion);
AudioConfig audioConfig = AudioConfig.fromDefaultMicrophoneInput();
SpeechRecognizer speechRecognizer = new SpeechRecognizer(speechConfig, audioConfig);
private final Runnable runnable = new Runnable() {
#Override
public void run() {
try{
int requestCode = 5; // unique code for the permission request
ActivityCompat.requestPermissions(MainActivity.this,
new String[] { RECORD_AUDIO, INTERNET }, requestCode);
try {
speechRecognizer.recognized.addEventListener((s, e) -> {
if (e.getResult().getReason() == ResultReason.RecognizedSpeech) {
System.out.println("RECOGNIZED: Text=" + e.getResult().getText());
String receivedText = e.getResult().getText();
attachEvent.success(receivedText);
} else if (e.getResult().getReason() == ResultReason.NoMatch) {
System.out.println("NOMATCH: Speech could not be recognized.");
try {
speechRecognizer.stopContinuousRecognitionAsync().get();
// attachEvent.endOfStream();
}
catch (Exception ex ) {
System.out.println(ex.getMessage());
}
}
});
speechRecognizer.canceled.addEventListener((s, e) -> {
System.out.println("CANCELED: Reason=" + e.getReason());
if (e.getReason() == CancellationReason.Error) {
System.out.println("CANCELED: ErrorCode=" + e.getErrorCode());
System.out.println("CANCELED: ErrorDetails=" + e.getErrorDetails());
System.out.println(
"CANCELED: Did you set the speech resource key and region values?");
}
try {
speechRecognizer.stopContinuousRecognitionAsync().get();
attachEvent.endOfStream();
}
catch (Exception ex ) {
System.out.println(ex.getMessage());
}
});
speechRecognizer.sessionStopped.addEventListener((s, e) -> {
System.out.println("\n top Session stopped event.");
try {
speechRecognizer.stopContinuousRecognitionAsync().get();
// attachEvent.endOfStream();
}
catch (Exception ex ) {
System.out.println(ex.getMessage());
}
});
speechRecognizer.startContinuousRecognitionAsync().get();
} catch(Exception e) {
System.out.println("*****************************************************");
System.out.println(e.getMessage());
try {
speechRecognizer.stopContinuousRecognitionAsync().get();
// attachEvent.endOfStream();
}
catch (Exception ex ) {
System.out.println(ex.getMessage());
}
}
} catch (Exception ex) {
System.out.println("+++++++++++++++++++++++++++++ Unexpected exception: " + ex.getMessage());
// recognizer.stopContinuousRecognitionAsync().get();
assert (false);
System.exit(1);
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new EventChannel(Objects.requireNonNull(getFlutterEngine()).getDartExecutor(), STREAM).setStreamHandler(
new EventChannel.StreamHandler() {
#Override
public void onListen(Object args, final EventChannel.EventSink events) {
Log.w(TAG_NAME, "Adding listener");
attachEvent = events;
count = 1;
handler = new Handler();
runnable.run();
}
#Override
public void onCancel(Object args) {
Log.w(TAG_NAME, "Cancelling listener");
try{
stopSpeechToText();
}
catch (Exception ex) {
System.out.println("-------------------------------------");
System.out.println(ex);
}
handler.removeCallbacks(runnable);
handler = null;
count = 1;
attachEvent = null;
System.out.println("StreamHandler - onCancelled: ");
}
}
);
}
public void stopSpeechToText() throws InterruptedException, ExecutionException,IOException {
speechRecognizer .sessionStopped.addEventListener((s, e) -> {
System.out.println("\n top Session stopped event.");
try {
speechRecognizer .stopContinuousRecognitionAsync().get();
// attachEvent.endOfStream();
}
catch (Exception ex ) {
System.out.println(ex.getMessage());
}
});
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(runnable);
handler = null;
attachEvent = null;
}
}
I have this code of main activity, I'm trying to make FTP server app but the problem which I'm getting is that when I click on Change directory button it shows internal storage path and I want both, internal and SD card storage. So please somebody help me solve this issue.
This is the code of main activity:
package com.project.shrey.ftptrial;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.TextInputLayout;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Switch;
import android.widget.TextView;
import net.rdrei.android.dirchooser.DirectoryChooserActivity;
import net.rdrei.android.dirchooser.DirectoryChooserConfig;
import org.apache.ftpserver.FtpServer;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.Authority;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.ftpserver.ftplet.FtpReply;
import org.apache.ftpserver.ftplet.FtpRequest;
import org.apache.ftpserver.ftplet.FtpSession;
import org.apache.ftpserver.ftplet.Ftplet;
import org.apache.ftpserver.ftplet.FtpletContext;
import org.apache.ftpserver.ftplet.FtpletResult;
import org.apache.ftpserver.ftplet.UserManager;
import org.apache.ftpserver.listener.ListenerFactory;
import org.apache.ftpserver.usermanager.PropertiesUserManagerFactory;
import org.apache.ftpserver.usermanager.SaltedPasswordEncryptor;
import org.apache.ftpserver.usermanager.impl.BaseUser;
import org.apache.ftpserver.usermanager.impl.WritePermission;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
Window window ;
TextView mAddrReg, mAddriOS, mPrompt, mPasswdDisp, mUserDisp, mDirAddress;
EditText mUser, mPasswd;
Switch mTogglePass;
LinearLayout mAddr1, mAddr2;
TextInputLayout mUserParent, mPasswdParent;
Button mDirChooser;
static String pass;
final int MY_PERMISSIONS_REQUEST = 2203;
final int REQUEST_DIRECTORY = 2108;
FtpServerFactory serverFactory = new FtpServerFactory();
ListenerFactory factory = new ListenerFactory();
PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
FtpServer finalServer;
Toolbar toolbar;
boolean justStarted = true;
#SuppressLint("AuthLeak")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(Build.VERSION.SDK_INT>=21){
window =this.getWindow();
window.setStatusBarColor(this.getResources().getColor(R.color.colordarkblue));
}
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
justStarted = false;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
});
builder.show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
}
}
mTogglePass = findViewById(R.id.togglePass);
mTogglePass.setEnabled(false);
mTogglePass.setChecked(false);
mUserParent = findViewById(R.id.userParent);
mUser = findViewById(R.id.user);
mUserDisp = findViewById(R.id.userDisp);
mPasswd = findViewById(R.id.passwd);
mPasswdDisp = findViewById(R.id.passwdDisp);
mPasswdParent = findViewById(R.id.passwdParent);
mPrompt = findViewById(R.id.prompt);
mAddrReg = findViewById(R.id.addrReg);
mAddr2 = findViewById(R.id.addr2);
mAddrReg.setText(String.format("ftp://%s:2121", wifiIpAddress(this)));
mAddriOS = findViewById(R.id.addriOS);
mAddr1 = findViewById(R.id.addr1);
mAddriOS.setText(String.format("ftp://ftp:ftp#%s:2121", wifiIpAddress(this)));
mDirAddress = findViewById(R.id.dirAddress);
mDirChooser= findViewById(R.id.dirChooser);
mDirChooser.setOnClickListener(view -> {
final Intent chooserIntent = new Intent(this, DirectoryChooserActivity.class);
final DirectoryChooserConfig config = DirectoryChooserConfig.builder()
.newDirectoryName("New Folder")
.allowNewDirectoryNameModification(true)
.build();
chooserIntent.putExtra(DirectoryChooserActivity.EXTRA_CONFIG, config);
startActivityForResult(chooserIntent, REQUEST_DIRECTORY);
});
finalServer = serverFactory.createServer();
toolbar.setOnClickListener(view -> {
try {
if (checkWifiOnAndConnected(this) || wifiHotspotEnabled(this)) {
MainActivity.this.serverControl();
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_wifi_message).setTitle(R.string.dialog_wifi_title);
builder.setPositiveButton("OK", (dialog, id) -> dialog.dismiss());
builder.show();
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
mTogglePass.setOnCheckedChangeListener((compoundButton, b) -> {
if (b) {
mPasswdDisp.setText(String.format("Password: %s", pass));
} else {
StringBuilder strB = new StringBuilder("Password: ");
for (int i=0; i < pass.length(); i++) {
strB.append('*');
}
mPasswdDisp.setText(strB.toString());
}
});
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST: {
if (grantResults.length <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message_exit).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
finish();
});
builder.show();
}
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_DIRECTORY) {
if (resultCode == DirectoryChooserActivity.RESULT_CODE_DIR_SELECTED) {
mDirAddress.setText(data.getStringExtra(DirectoryChooserActivity.RESULT_SELECTED_DIR));
}
}
}
#Override
protected void onDestroy() {
try {
finalServer.stop();
} catch (Exception e) {
Log.e("Server Close Error", e.getCause().toString());
}
super.onDestroy();
}
private void setupStart(String username, String password, String subLoc) throws FileNotFoundException {
factory.setPort(2121);
serverFactory.addListener("default", factory.createListener());
File files = new File(Environment.getExternalStorageDirectory().getPath() + "/users.properties");
if (!files.exists()) {
try {
files.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
userManagerFactory.setFile(files);
userManagerFactory.setPasswordEncryptor(new SaltedPasswordEncryptor());
UserManager um = userManagerFactory.createUserManager();
BaseUser user = new BaseUser();
user.setName(username);
user.setPassword(password);
String home = Environment.getExternalStorageDirectory().getPath() + "/" + subLoc;
user.setHomeDirectory(home);
List<Authority> auths = new ArrayList<>();
Authority auth = new WritePermission();
auths.add(auth);
user.setAuthorities(auths);
try {
um.save(user);
} catch (FtpException e1) {
e1.printStackTrace();
}
serverFactory.setUserManager(um);
Map<String, Ftplet> m = new HashMap<>();
m.put("miaFtplet", new Ftplet()
{
#Override
public void init(FtpletContext ftpletContext) throws FtpException {
}
#Override
public void destroy() {
}
#Override
public FtpletResult beforeCommand(FtpSession session, FtpRequest request) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult afterCommand(FtpSession session, FtpRequest request, FtpReply reply) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult onConnect(FtpSession session) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
#Override
public FtpletResult onDisconnect(FtpSession session) throws FtpException, IOException
{
return FtpletResult.DEFAULT;
}
});
serverFactory.setFtplets(m);
}
private String wifiIpAddress(Context context) {
try {
if (wifiHotspotEnabled(context)) {
return "192.168.43.1";
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return Utils.getIPAddress(true);
}
private boolean wifiHotspotEnabled(Context context) throws InvocationTargetException, IllegalAccessException {
WifiManager manager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
Method method = null;
try {
method = manager.getClass().getDeclaredMethod("isWifiApEnabled");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
method.setAccessible(true); //in the case of visibility change in future APIs
return (Boolean) method.invoke(manager);
}
private boolean checkWifiOnAndConnected(Context context) {
WifiManager wifiMgr = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
assert wifiMgr != null;
if (wifiMgr.isWifiEnabled()) { // Wi-Fi adapter is ON
WifiInfo wifiInfo = wifiMgr.getConnectionInfo();
return wifiInfo.getNetworkId() != -1;
}
else {
return false; // Wi-Fi adapter is OFF
}
}
#Override
public void onBackPressed() {
finalServer.stop();
findViewById(R.id.toolbar).setEnabled(false);
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colorbluelight, null));
super.onBackPressed();
}
void serverControl() {
if (finalServer.isStopped()) {
mUser.setEnabled(false);
mPasswd.setEnabled(false);
mDirChooser.setEnabled(false);
String user = mUser.getText().toString();
String passwd = mPasswd.getText().toString();
if (user.isEmpty()) {
user = "ftp";
}
if (passwd.isEmpty()) {
passwd = "ftp";
}
String subLoc = mDirAddress.getText().toString().substring(20);
pass = passwd;
StringBuilder strB = new StringBuilder("Password: ");
for (int i=0; i < pass.length(); i++) {
strB.append('*');
}
mPasswdDisp.setText(strB.toString());
mUserDisp.setText(String.format("Username: %s", user));
mUserDisp.setVisibility(View.VISIBLE);
mUserParent.setVisibility(View.INVISIBLE);
mPasswdParent.setVisibility(View.INVISIBLE);
mPasswdDisp.setVisibility(View.VISIBLE);
try {
setupStart(user, passwd, subLoc);
} catch (FileNotFoundException fnfe) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.dialog_message_error).setTitle(R.string.dialog_title);
builder.setPositiveButton("OK", (dialog, id) -> {
dialog.dismiss();
justStarted = false;
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
});
builder.show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST);
}
}
try {
finalServer.start();
mAddrReg.setText(String.format("ftp://%s:2121", wifiIpAddress(this)));
mAddriOS.setText(String.format("ftp://%s:%s#%s:2121", user, passwd, wifiIpAddress(this)));
} catch (FtpException e) {
e.printStackTrace();
}
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colordarkblue, null));
mPrompt.setVisibility(View.VISIBLE);
mAddr1.setVisibility(View.VISIBLE);
mAddr2.setVisibility(View.VISIBLE);
mTogglePass.setEnabled(true);
} else if (finalServer.isSuspended()) {
finalServer.resume();
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colordarkblue, null));
mPrompt.setVisibility(View.VISIBLE);
mAddr1.setVisibility(View.VISIBLE);
mAddr2.setVisibility(View.VISIBLE);
} else {
finalServer.suspend();
toolbar.setBackgroundColor(ResourcesCompat.getColor(getResources(), R.color.colorbluelight, null));
mPrompt.setVisibility(View.INVISIBLE);
mAddr1.setVisibility(View.INVISIBLE);
mAddr2.setVisibility(View.INVISIBLE);
}
}
}
I a working on Pokedex by cs50 and facing a lot of trouble. I am always getting true when i call this..
val = getPreferences(Context.MODE_PRIVATE).getBoolean(nameTextView.getText().toString(), false);
if (val == false){
buttonView.setText("Catch");
} else {
buttonView.setText("Release");
}
I know the chnages are getting saved to the preference because , this is working properly when i trigger the button;
public void toggleCatch(View view) {
boolean val = getPreferences(Context.MODE_PRIVATE).getBoolean(nameTextView.getText().toString(), false);
if (!val){
buttonView.setText("Release1");
getPreferences(Context.MODE_PRIVATE).edit().putBoolean(nameTextView.getText().toString(), true).commit();
} else {
buttonView.setText("Catch1");
getPreferences(Context.MODE_PRIVATE).edit().putBoolean(nameTextView.getText().toString(), false).commit();
}
}
this is my full code of the activity
package edu.harvard.cs50.pokedex;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;
public class PokemonActivity extends AppCompatActivity {
private TextView nameTextView;
private TextView numberTextView;
private TextView type1TextView;
private TextView type2TextView;
private TextView descView;
private Button buttonView;
private ImageView spriteView;
private String url;
private String desc_url;
private RequestQueue requestQueue;
private int id;
boolean val;
#SuppressLint("SetTextI18n")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pokemon);
requestQueue = Volley.newRequestQueue(getApplicationContext());
url = getIntent().getStringExtra("url");
nameTextView = findViewById(R.id.pokemon_name);
numberTextView = findViewById(R.id.pokemon_number);
type1TextView = findViewById(R.id.pokemon_type1);
type2TextView = findViewById(R.id.pokemon_type2);
buttonView = findViewById(R.id.catch_button);
spriteView = findViewById(R.id.spriteView);
descView = findViewById(R.id.descView);
load();
val = getPreferences(
Context.MODE_PRIVATE
).getBoolean(nameTextView.getText().toString(),false);
if (val == false){
buttonView.setText("Catch");
} else {
buttonView.setText("Release");
}
}
private class DownloadSpriteTask extends AsyncTask<String, Void, Bitmap> {
#Override
protected Bitmap doInBackground(String... strings) {
try {
URL url = new URL(strings[0]);
return BitmapFactory.decodeStream(url.openStream());
}
catch (IOException e) {
Log.e("cs50", "Download sprite error", e);
return null;
}
}
#Override
protected void onPostExecute(Bitmap bitmap) {
spriteView.setImageBitmap(bitmap);
}
}
public void load() {
type1TextView.setText("");
type2TextView.setText("");
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
nameTextView.setText(response.getString("name"));
numberTextView.setText(String.format("#%03d", response.getInt("id")));
id = response.getInt("id");
desc_url = String.format("https://pokeapi.co/api/v2/pokemon-species/%d/", id);
JsonObjectRequest request2 = new JsonObjectRequest(Request.Method.GET, desc_url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray desc_array = response.getJSONArray("flavor_text_entries");
Log.d("ved", "Flavor text entries loaded");
for (int i = 0; i < desc_array.length(); i++) {
JSONObject desc = desc_array.getJSONObject(i);
if (desc.getJSONObject("language").getString("name").equals("en")) {
descView.setText(desc.getString("flavor_text"));
break;
}
}
} catch (JSONException e) {
Log.e("ved", "desc" + e);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("ved", "Pokemon desc error", error);
}
});
requestQueue.add(request2);
JSONArray typeEntries = response.getJSONArray("types");
JSONObject spriteEntries = response.getJSONObject("sprites");
String img_url = spriteEntries.getString("front_default");
new DownloadSpriteTask().execute(img_url);
for (int i = 0; i < typeEntries.length(); i++) {
JSONObject typeEntry = typeEntries.getJSONObject(i);
int slot = typeEntry.getInt("slot");
String type = typeEntry.getJSONObject("type").getString("name");
if (slot == 1) {
type1TextView.setText(type);
}
else if (slot == 2) {
type2TextView.setText(type);
}
}
} catch (JSONException e) {
Log.e("cs50", "Pokemon json error", e);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("cs50", "Pokemon details error", error);
}
});
requestQueue.add(request);
}
//shared presferences intially all values to false
#SuppressLint({"ApplySharedPref", "SetTextI18n"})
public void toggleCatch(View view) {
boolean val = getPreferences(Context.MODE_PRIVATE).getBoolean(nameTextView.getText().toString(), false);
if (!val){
buttonView.setText("Release1");
getPreferences(Context.MODE_PRIVATE).edit().putBoolean(nameTextView.getText().toString(), true).commit();
} else {
buttonView.setText("Catch1");
getPreferences(Context.MODE_PRIVATE).edit().putBoolean(nameTextView.getText().toString(), false).commit();
}
}
}
I have to implement save to my preferences such that it remember if I,hve catched ny pokemons , if I reopen the app it much display the same..
You can try below code.
As variable type is boolean, you can directly use it as condition in if block.
val = getPreferences(Context.MODE_PRIVATE).getBoolean(nameTextView.getText().toString(), false);
if (!val){
buttonView.setText("Catch");
} else {
buttonView.setText("Release");
}
There's an error in your code. Instead of checking if val is false, you're setting false to it:
if (val = false)
You can fix that by
if (val == false)
Please, check if that's what is causing the issue.
I'm using react native v0.49 and installed react-native-nfc-manager .
when I try to use nfc I get the error
Attempt to get length of null array
so I checked on the nfc folder and I find the issue into the plugin installation
#ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}
as you can see when the nfcAdapter is not null it
callback.invoke(null)
so here is the problem, so I tried to change it to
callback.invoke(LOG_TAG)
and it's not show the error but I don't get any nfc tag, is show me undefined but not error.
what can i do?
here is all the NfcManager.java file
package community.revteltech.nfc;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Base64;
import android.util.Log;
import android.provider.Settings;
import com.facebook.react.bridge.*;
import com.facebook.react.modules.core.RCTNativeAppEventEmitter;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.net.Uri;
import android.nfc.FormatException;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.nfc.Tag;
import android.nfc.TagLostException;
import android.nfc.tech.Ndef;
import android.nfc.tech.NdefFormatable;
import android.os.Parcelable;
import org.json.JSONObject;
import org.json.JSONException;
import java.util.*;
import static android.app.Activity.RESULT_OK;
import static android.os.Build.VERSION_CODES.LOLLIPOP;
import static com.facebook.react.bridge.UiThreadUtil.runOnUiThread;
class NfcManager extends ReactContextBaseJavaModule implements ActivityEventListener, LifecycleEventListener {
private static final String LOG_TAG = "NfcManager";
private final List<IntentFilter> intentFilters = new ArrayList<IntentFilter>();
private final ArrayList<String[]> techLists = new ArrayList<String[]>();
private Context context;
private ReactApplicationContext reactContext;
private Boolean isForegroundEnabled = false;
private Boolean isResumed = false;
public NfcManager(ReactApplicationContext reactContext) {
super(reactContext);
context = reactContext;
this.reactContext = reactContext;
reactContext.addActivityEventListener(this);
reactContext.addLifecycleEventListener(this);
Log.d(LOG_TAG, "NfcManager created");
}
#Override
public String getName() {
return "NfcManager";
}
#ReactMethod
public void start(Callback callback) {
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Log.d(LOG_TAG, "start");
callback.invoke(null);
} else {
Log.d(LOG_TAG, "not support in this device");
callback.invoke("no nfc support");
}
}
#ReactMethod
public void isEnabled(Callback callback) {
Log.d(LOG_TAG, "isEnabled");
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
callback.invoke(null, nfcAdapter.isEnabled());
} else {
callback.invoke(null, false);
}
}
#ReactMethod
public void goToNfcSetting(Callback callback) {
Log.d(LOG_TAG, "goToNfcSetting");
Activity currentActivity = getCurrentActivity();
currentActivity.startActivity(new Intent(Settings.ACTION_NFC_SETTINGS));
callback.invoke();
}
#ReactMethod
public void getLaunchTagEvent(Callback callback) {
Activity currentActivity = getCurrentActivity();
Intent launchIntent = currentActivity.getIntent();
WritableMap nfcTag = parseNfcIntent(launchIntent);
callback.invoke(null, nfcTag);
}
#ReactMethod
private void registerTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = true;
// capture all mime-based dispatch NDEF
IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
try {
ndef.addDataType("*/*");
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("fail", e);
}
intentFilters.add(ndef);
// capture all rest NDEF, such as uri-based
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED));
techLists.add(new String[]{Ndef.class.getName()});
// for those without NDEF, get them as tags
intentFilters.add(new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED));
if (isResumed) {
enableDisableForegroundDispatch(true);
}
callback.invoke();
}
#ReactMethod
private void unregisterTagEvent(Callback callback) {
Log.d(LOG_TAG, "registerTag");
isForegroundEnabled = false;
intentFilters.clear();
if (isResumed) {
enableDisableForegroundDispatch(false);
}
callback.invoke();
}
#Override
public void onHostResume() {
Log.d(LOG_TAG, "onResume");
isResumed = true;
if (isForegroundEnabled) {
enableDisableForegroundDispatch(true);
}
}
#Override
public void onHostPause() {
Log.d(LOG_TAG, "onPause");
isResumed = false;
enableDisableForegroundDispatch(false);
}
#Override
public void onHostDestroy() {
Log.d(LOG_TAG, "onDestroy");
}
private void enableDisableForegroundDispatch(boolean enable) {
Log.i(LOG_TAG, "enableForegroundDispatch, enable = " + enable);
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
Activity currentActivity = getCurrentActivity();
if (nfcAdapter != null && !currentActivity.isFinishing()) {
try {
if (enable) {
nfcAdapter.enableForegroundDispatch(currentActivity, getPendingIntent(), getIntentFilters(), getTechLists());
} else {
nfcAdapter.disableForegroundDispatch(currentActivity);
}
} catch (IllegalStateException e) {
Log.w(LOG_TAG, "Illegal State Exception starting NFC. Assuming application is terminating.");
}
}
}
private PendingIntent getPendingIntent() {
Activity activity = getCurrentActivity();
Intent intent = new Intent(activity, activity.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
return PendingIntent.getActivity(activity, 0, intent, 0);
}
private IntentFilter[] getIntentFilters() {
return intentFilters.toArray(new IntentFilter[intentFilters.size()]);
}
private String[][] getTechLists() {
return techLists.toArray(new String[0][0]);
}
private void sendEvent(String eventName,
#Nullable WritableMap params) {
getReactApplicationContext()
.getJSModule(RCTNativeAppEventEmitter.class)
.emit(eventName, params);
}
private void sendEventWithJson(String eventName,
JSONObject json) {
try {
WritableMap map = JsonConvert.jsonToReact(json);
sendEvent(eventName, map);
} catch (JSONException ex) {
Log.d(LOG_TAG, "fireNdefEvent fail: " + ex);
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "onReceive " + intent);
}
};
#Override
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
Log.d(LOG_TAG, "onActivityResult");
}
#Override
public void onNewIntent(Intent intent) {
Log.d(LOG_TAG, "onNewIntent " + intent);
WritableMap nfcTag = parseNfcIntent(intent);
if (nfcTag != null) {
sendEvent("NfcManagerDiscoverTag", nfcTag);
}
}
private WritableMap parseNfcIntent(Intent intent) {
Log.d(LOG_TAG, "parseIntent " + intent);
String action = intent.getAction();
Log.d(LOG_TAG, "action " + action);
if (action == null) {
return null;
}
WritableMap parsed = null;
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
// Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED)) {
Ndef ndef = Ndef.get(tag);
Parcelable[] messages = intent.getParcelableArrayExtra((NfcAdapter.EXTRA_NDEF_MESSAGES));
parsed = ndef2React(ndef, messages);
} else if (action.equals(NfcAdapter.ACTION_TECH_DISCOVERED)) {
for (String tagTech : tag.getTechList()) {
Log.d(LOG_TAG, tagTech);
if (tagTech.equals(NdefFormatable.class.getName())) {
// fireNdefFormatableEvent(tag);
} else if (tagTech.equals(Ndef.class.getName())) { //
Ndef ndef = Ndef.get(tag);
parsed = ndef2React(ndef, new NdefMessage[] { ndef.getCachedNdefMessage() });
}
}
} else if (action.equals(NfcAdapter.ACTION_TAG_DISCOVERED)) {
parsed = tag2React(tag);
}
return parsed;
}
private WritableMap tag2React(Tag tag) {
try {
JSONObject json = Util.tagToJSON(tag);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}
}
private WritableMap ndef2React(Ndef ndef, Parcelable[] messages) {
try {
JSONObject json = buildNdefJSON(ndef, messages);
return JsonConvert.jsonToReact(json);
} catch (JSONException ex) {
return null;
}
}
JSONObject buildNdefJSON(Ndef ndef, Parcelable[] messages) {
JSONObject json = Util.ndefToJSON(ndef);
// ndef is null for peer-to-peer
// ndef and messages are null for ndef format-able
if (ndef == null && messages != null) {
try {
if (messages.length > 0) {
NdefMessage message = (NdefMessage) messages[0];
json.put("ndefMessage", Util.messageToJSON(message));
// guessing type, would prefer a more definitive way to determine type
json.put("type", "NDEF Push Protocol");
}
if (messages.length > 1) {
Log.d(LOG_TAG, "Expected one ndefMessage but found " + messages.length);
}
} catch (JSONException e) {
// shouldn't happen
Log.e(Util.TAG, "Failed to convert ndefMessage into json", e);
}
}
return json;
}
}
my nfc component
import React, { Component } from 'react';
import {
View,
Text,
Button,
Platform,
TouchableOpacity,
Linking
} from 'react-native';
import NfcManager, {NdefParser} from 'react-native-nfc-manager';
class NFC extends Component {
constructor(props) {
super(props);
this.state = {
supported: true,
enabled: false,
tag: {},
}
}
componentDidMount() {
NfcManager.start({
onSessionClosedIOS: () => {
console.log('ios session closed');
}
})
.then(result => {
console.log('start OK', result);
})
.catch(error => {
console.warn('start fail', error);
this.setState({supported: false});
})
if (Platform.OS === 'android') {
NfcManager.getLaunchTagEvent()
.then(tag => {
console.log('launch tag', tag);
if (tag) {
this.setState({ tag });
}
})
.catch(err => {
console.log(err);
})
NfcManager.isEnabled()
.then(enabled => {
this.setState({ enabled });
})
.catch(err => {
console.log(err);
})
}
}
render() {
let { supported, enabled, tag } = this.state;
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>{`Is NFC supported ? ${supported}`}</Text>
<Text>{`Is NFC enabled (Android only)? ${enabled}`}</Text>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._startDetection}>
<Text style={{ color: 'blue' }}>Start Tag Detection</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._stopDetection}>
<Text style={{ color: 'red' }}>Stop Tag Detection</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._clearMessages}>
<Text>Clear</Text>
</TouchableOpacity>
<TouchableOpacity style={{ marginTop: 20 }} onPress={this._goToNfcSetting}>
<Text >Go to NFC setting</Text>
</TouchableOpacity>
<Text style={{ marginTop: 20 }}>{`Current tag JSON: ${JSON.stringify(tag)}`}</Text>
</View>
)
}
_onTagDiscovered = tag => {
console.log('Tag Discovered', tag);
this.setState({ tag });
let url = this._parseUri(tag);
if (url) {
Linking.openURL(url)
.catch(err => {
console.warn(err);
})
}
}
_startDetection = () => {
NfcManager.registerTagEvent(this._onTagDiscovered)
.then(result => {
console.log('registerTagEvent OK', result)
})
.catch(error => {
console.warn('registerTagEvent fail', error)
})
}
_stopDetection = () => {
NfcManager.unregisterTagEvent()
.then(result => {
console.log('unregisterTagEvent OK', result)
})
.catch(error => {
console.warn('unregisterTagEvent fail', error)
})
}
_clearMessages = () => {
this.setState({tag: null});
}
_goToNfcSetting = () => {
if (Platform.OS === 'android') {
NfcManager.goToNfcSetting()
.then(result => {
console.log('goToNfcSetting OK', result)
})
.catch(error => {
console.warn('goToNfcSetting fail', error)
})
}
}
_parseUri = (tag) => {
let result = NdefParser.parseUri(tag.ndefMessage[0]),
uri = result && result.uri;
if (uri) {
console.log('parseUri: ' + uri);
return uri;
}
return null;
}
}
export default NFC;
Be careful, NFC could not be available in all devices, so you have to check first:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null){
Toast.makeText(this, "NFC not available", Toast.LENGTH_SHORT).show();
return;
}else{
Toast.makeText(this, "NFC is avalable", Toast.LENGTH_SHORT).show();
}
....
....
}
If NFC is not present that will be the reason to get the error message:
Attempt to get length of null array on NfcManager.start()
Below I've listed my activity code, call out to the web service, and the json parsing class I created to parse the web service results. I'm trying to pass a user object back to the activity to determine what they can/can't do, however, I'm not getting past the "after execute" log statement. onRequestFinished never gets called which is where I would have expected it to end up. Any help would be greatly appreciated as there doesn't seem to be much activity with DataDroid...
LoginActivity.java
package com.motosho.ui;
import com.foxykeep.datadroid.requestmanager.Request;
import com.foxykeep.datadroid.requestmanager.RequestManager.RequestListener;
import com.motosho.R;
import com.motosho.data.model.User;
import com.motosho.data.requestmanager.RequestFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.content.Intent;
public final class LoginActivity extends DataDroidActivity implements RequestListener,
OnClickListener {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
bindViews();
}
protected void onResume() {
super.onResume();
for(int i=0; i < mRequestList.size(); i++) {
Request request = mRequestList.get(i);
if(mRequestManager.isRequestInProgress(request)) {
mRequestManager.addRequestListener(this, request);
setProgressBarIndeterminateVisibility(true);
} else {
mRequestManager.callListenerWithCachedData(this, request);
i--;
mRequestList.remove(request);
}
}
}
protected void onPause() {
super.onPause();
if(!mRequestList.isEmpty()) {
mRequestManager.removeRequestListener(this);
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
}
private void bindViews() {
((Button) findViewById(R.id.sign_in_button)).setOnClickListener(this);
}
private void callLoginWS(String username, String pin, String eventId) {
Log.i("LOGIN", "in callLoginWS - username=" + username + ", pin=" + pin + ", eventid=" + eventId);
setProgressBarIndeterminateVisibility(true);
Request request = RequestFactory.getLoginRequest(username, pin, eventId);
mRequestManager.execute(request, this);
Log.i("LOGIN", "after execute");
mRequestList.add(request);
}
public void onClick(View view) {
switch(view.getId()) {
case R.id.sign_in_button:
EditText emailText = (EditText) findViewById(R.id.email);
EditText pinText = (EditText) findViewById(R.id.pin);
Log.i("LOGIN","set email and pin text");
callLoginWS(emailText.getText().toString(), pinText.getText().toString(),"9");
break;
}
}
#Override
public void onRequestFinished(Request request, Bundle resultData) {
Log.i("LOGIN", "inside onRequestFinished");
if(mRequestList.contains(request)) {
setProgressBarIndeterminateVisibility(false);
Log.i("LOGIN", "request found");
mRequestList.remove(request);
Toast toast = Toast.makeText(this, "request finished", Toast.LENGTH_SHORT);
toast.show();
User user = resultData.getParcelable("user");
if(user != null) {
startActivity(new Intent(this, MainActivity.class).putExtras(resultData));
}
}
}
#Override
public void onRequestConnectionError(Request request, int statusCode) {
Log.i("LOGIN", "onRequestConnectionError");
if(mRequestList.contains(request)) {
setProgressBarIndeterminateVisibility(false);
//show error
Toast toast = Toast.makeText(this, "connection error", Toast.LENGTH_SHORT);
toast.show();
mRequestList.remove(request);
}
}
#Override
public void onRequestDataError(Request request) {
Log.i("LOGIN", "onRequestDataError");
if(mRequestList.contains(request)) {
setProgressBarIndeterminateVisibility(false);
mRequestList.remove(request);
//show error
Toast toast = Toast.makeText(this, "data error", Toast.LENGTH_SHORT);
toast.show();
}
}
#Override
public void onRequestCustomError(Request request, Bundle resultData) {
// Never called
}
public void connectionErrorDialogRetry(Request request) {
Log.i("LOGIN", "connectionErrorDialogRetry");
String username = request.getString("username");
String pin = request.getString("pin");
String eventId = request.getString("eventid");
callLoginWS(username,pin,eventId);
}
}
LoginOperation.java
package com.motosho.data.operation;
import java.util.HashMap;
import android.content.Context;
import android.os.Bundle;
import com.foxykeep.datadroid.exception.ConnectionException;
import com.foxykeep.datadroid.exception.CustomRequestException;
import com.foxykeep.datadroid.exception.DataException;
import com.foxykeep.datadroid.network.NetworkConnection;
import com.foxykeep.datadroid.network.NetworkConnection.ConnectionResult;
import com.foxykeep.datadroid.network.NetworkConnection.Method;
import com.foxykeep.datadroid.requestmanager.Request;
import com.foxykeep.datadroid.service.RequestService.Operation;
import com.motosho.config.WSConfig;
import com.motosho.data.factory.LoginJsonFactory;
public final class LoginOperation implements Operation {
#Override
public Bundle execute(Context context, Request request)
throws ConnectionException, DataException, CustomRequestException {
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", request.getString("username"));
params.put("pin", request.getString("pin"));
params.put("eventid", request.getString("eventid"));
NetworkConnection networkConnection = new NetworkConnection(context, WSConfig.WS_LOGIN_URL);
networkConnection.setMethod(Method.POST);
networkConnection.setParameters(params);
ConnectionResult result = networkConnection.execute();
return LoginJsonFactory.parseResult(result.body);
}
}
LoginJsonFactory.java
package com.motosho.data.factory;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.Bundle;
import android.util.Log;
import com.foxykeep.datadroid.exception.DataException;
import com.motosho.config.JSONTag;
import com.motosho.data.model.User;
public final class LoginJsonFactory {
private static final String TAG = LoginJsonFactory.class.getName();
private LoginJsonFactory() { }
#SuppressWarnings("null")
public static Bundle parseResult(String wsResponse) throws DataException {
User user = new User();
try {
JSONObject parser = new JSONObject(wsResponse);
JSONObject jsonRoot = parser.getJSONObject(JSONTag.USER_ELEM);
user.firstName = jsonRoot.getString(JSONTag.USER_ELEM_FIRST_NAME);
user.lastName = jsonRoot.getString(JSONTag.USER_ELEM_LAST_NAME);
user.phoneNumber = jsonRoot.getString(JSONTag.USER_ELEM_PHONE_NUMBER);
user.role = jsonRoot.getString(JSONTag.USER_ELEM_ROLE);
JSONArray jsonPositionsArray = jsonRoot.getJSONArray(JSONTag.USER_ELEM_LIST_POSITIONS);
int size = jsonPositionsArray.length();
List<String> tempPositionsArray = null;
for (int i=0; i < size; i++) {
tempPositionsArray.add(jsonPositionsArray.getString(i));
}
user.positions = tempPositionsArray;
JSONArray jsonCapabilitiesArray = jsonRoot.getJSONArray(JSONTag.USER_ELEM_LIST_CAPABILITIES);
size = jsonCapabilitiesArray.length();
List<String> tempCapabilitiesArray = null;
for(int i=0; i < size; i++) {
tempCapabilitiesArray.add(jsonCapabilitiesArray.getString(i));
}
user.capabilities = tempCapabilitiesArray;
} catch (JSONException e) {
Log.e(TAG, "JSONException", e);
throw new DataException(e);
}
Bundle bundle = new Bundle();
bundle.putParcelable("user", user);
return bundle;
}
}