My problem is that I am getting an extremely low-quality picture from the camera when I display it on the imageView. The size of imageView is set to 250dpx250dp in the .xml.
Here is my code for capturing camera image:
class Category_Description : Fragment() {
var mBitmap: Bitmap? = null
private val ALL_PERMISSIONS_RESULT = 107
private val IMAGE_RESULT = 200
private val REQUEST_IMAGE_CAPTURE = 12345
var photo: Bitmap?=null
var resizedPhoto:Bitmap?=null
var imageUri: Uri?=null
var filePath:String?=null
var cursor:Cursor?=null
var reqFile:RequestBody?=null
var intermediate:String?=null
var outputFileUri: Uri? = null
var camera_FAB: FloatingActionButton? = null
var upload_FAB: FloatingActionButton? = null
var imageView:ImageView?= null
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
// val permissions = arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE,
// android.Manifest.permission.CAMERA)
// requestPermissions( permissions,1)
val v = inflater.inflate(com.example.atry.R.layout.fragment_category__description, container, false)
camera_FAB = v.findViewById(com.example.atry.R.id.camera)
upload_FAB= v.findViewById(com.example.atry.R.id.upload)
imageView = v.findViewById<ImageView>(com.example.atry.R.id.display_image)
}
upload_FAB!!.setOnClickListener {
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED) {
// }
// }
pickImageFromGallery()
}
camera_FAB!!.setOnClickListener{
val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
// intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri)
val frag = this
/** Pass your fragment reference **/
frag.startActivityForResult(
intent,
REQUEST_IMAGE_CAPTURE
) // REQUEST_IMAGE_CAPTURE = 12345
}
fun hasPermissionInManifest(context: Context, permissionName: String): Boolean {
val packageName = context.packageName
try {
val packageInfo = context.packageManager
.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
val declaredPermisisons = packageInfo.requestedPermissions
if (declaredPermisisons != null && declaredPermisisons.size > 0) {
for (p in declaredPermisisons) {
if (p == permissionName) {
return true
}
}
}
} catch (e: PackageManager.NameNotFoundException) {
}
return false
}
private fun pickImageFromGallery() {
//Intent to pick image
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
startActivityForResult(intent, IMAGE_PICK_CODE)
}
companion object {
//image pick code
private val IMAGE_PICK_CODE = 1000;
//Permission code
private val PERMISSION_CODE = 1001;
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK && data !=null) {
if (requestCode == REQUEST_IMAGE_CAPTURE){
val imageView = view!!.findViewById<ImageView>(R.id.display_image)
//FOR CAMERA CAPTURE
photo = data.getExtras()!!.get("data") as Bitmap
val uri = getImageUriFromBitmap(activity!!,photo!!)
filePath = getPathFromURI(uri)
Picasso.get().load(uri).into(imageView)
intermediate = activity!!.contentResolver.getType(uri)
} else if(requestCode== IMAGE_PICK_CODE) {
val imageView = view!!.findViewById<ImageView>(R.id.display_image)
// Get image URI From intent FOR UPLOADING
imageUri = data.data
intermediate = activity!!.contentResolver.getType(imageUri!!)
filePath = getImageFilePath(data)
if (filePath != null) {
mBitmap = BitmapFactory.decodeFile(filePath)
imageView.setImageBitmap(mBitmap)
cursor!!.close()
}
}
}
super.onActivityResult(requestCode, resultCode, data)
}
fun getImageFilePath(data: Intent): String {
return getImageFromFilePath(data)
}
private fun getImageFromFilePath(data: Intent?): String {
val isCamera = data == null || data.data == null
return if (isCamera)
getCaptureImageOutputUri()!!.path!!
else
getPathFromURI(data!!.data!!)
}
private fun getCaptureImageOutputUri(): Uri? {
val getImage = activity!!.getExternalFilesDir("")
if (getImage != null) {
outputFileUri = Uri.fromFile(File(getImage.path, "profile.png"))
}
return outputFileUri
}
private fun getImageUri(inContext: Context, inImage: Bitmap): Uri {
val bytes = ByteArrayOutputStream()
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
val path =
MediaStore.Images.Media.insertImage(inContext.contentResolver, inImage, "Title", null)
return Uri.parse(path)
}
fun getImageUriFromBitmap(activity: Activity, bitmap: Bitmap): Uri{
val bytes = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes)
val path = MediaStore.Images.Media.insertImage(activity.contentResolver, bitmap, "Title", null)
return Uri.parse(path.toString())
}
private fun getPathFromURI(contentUri: Uri): String {
val proj = arrayOf(MediaStore.Images.Media.DATA)
cursor = activity!!.contentResolver.query(contentUri, proj, null, null, null)
if(cursor!=null)
cursor!!.moveToFirst()
val column_index = cursor!!.getColumnIndex(proj[0])
return cursor!!.getString(column_index)
}
}
Related
I have made a pretty decently working Map to String + Back converter but I am wondering if there is an easier way to do this. I am basically just trying to store the Map into an sqlite database and read from it later.
public class mainFunctions {
public String toString(Object object) {
String objectClass = object.getClass().getName();
String objectString = String.format("%s[", objectClass);
int index = -1;
if(objectClass.contains("Map")) {
Map<Object, Object> map = null;
if (objectClass.contains(TreeMap.class.getName())) { map = (TreeMap) object; }
else if (objectClass.contains(HashMap.class.getName())) { map = (HashMap) object; }
else if (objectClass.contains(LinkedHashMap.class.getName())) { map = (LinkedHashMap) object; }
else { return null; }
for (Object key : map.keySet()) {
index ++;
Object value = map.get(key);
objectString = String.format("%s%s[\"%s\":\"%s\"]", objectString, index > 0 ? "," : "", key, value);
}
objectString = String.format("%s]", objectString);
return objectString;
} else {
List<Object> list;
if (objectClass.contains(ArrayList.class.getName())) { list = (ArrayList) object; }
else if (objectClass.contains(Vector.class.getName())) { list = (Vector) object; }
else if (objectClass.contains(LinkedList.class.getName())) { list = (LinkedList) object; }
else { return null; }
for (Object obj : list) {
index ++;
objectString = String.format("%s%s[\"%s\"]", objectString, index > 0 ? "," : "", obj);
}
objectString = String.format("%s]", objectString);
return objectString;
}
}
public Object fromString(String objectString) {
String objectClass = objectString.split("\\[")[0];
objectString = objectString.replace(String.format("%s[", objectClass), "");
objectString = objectString.substring(2, objectString.length() - 3);
String[] objectSplit = objectString.split("\"],\\[\"");
if(objectClass.contains("Map")) {
Map<Object, Object> map = null;
if (objectClass.contains(TreeMap.class.getName())) { map = new TreeMap<>(); }
else if (objectClass.contains(HashMap.class.getName())) { map = new HashMap<>(); }
else if (objectClass.contains(LinkedHashMap.class.getName())) { map = new TreeMap<>(); }
else { return null; }
int index = -1;
for (String entry : objectSplit) { String[] entrySplit = entry.split("\":\""); map.put(entrySplit[0], entrySplit[1]); }
return map;
} else {
List<Object> list;
if (objectClass.contains(ArrayList.class.getName())) { list = new ArrayList<>();
} else if (objectClass.contains(Vector.class.getName())) { list = new Vector<>();
} else if (objectClass.contains(LinkedList.class.getName())) { list = new LinkedList<>();
} else { return null; }
for (String entry : objectSplit) { list.add(entry); }
return list;
}
}
}
This is the usage:
TreeMap<String, Double> itemValues = new TreeMap<>();
itemValues.put("diamond", 111.11);
itemValues.put("netherite_ingot", 555.55);
itemValues.put("emerald", 2.22);
itemValues.put("gold_ingot", 12.22);
String itemString = this.functions.toString(itemValues);
this.log(String.format("%sitemValues String = %s", header, itemString));
TreeMap<String, Double> values;
values = (TreeMap<String, Double>) this.functions.fromString(itemString);
this.log(String.format("%sitemValues TreeMap = %s", header, values));
ArrayList<String> items = new ArrayList<>();
items.add("diamond");
items.add("netherite_ingot");
items.add("emerald");
items.add("gold_ingot");
String itemss = this.functions.toString(items);
this.log(String.format("%sitems String = %s", header, itemss));
ArrayList<String> valuesAr;
valuesAr = (ArrayList<String>) this.functions.fromString(itemss);
this.log(String.format("%sitems Array = %s", header, valuesAr));
And this is the Output:
itemValues String = java.util.TreeMap[["diamond":"111.11"],["emerald":"2.22"],["gold_ingot":"12.22"],["netherite_ingot":"555.55"]]
itemValues TreeMap = {diamond=111.11, emerald=2.22, gold_ingot=12.22, netherite_ingot=555.55}
items String = java.util.ArrayList[["diamond"],["netherite_ingot"],["emerald"],["gold_ingot"]]
items Array = [diamond, netherite_ingot, emerald, gold_ingot]
Seems to all work well but assuming there is a better way to do this.
I have been using my own preference class derived from EditTextPreference to include a neutral button (so that the user can select a default value).
I did this by overriding onPrepareDialogBuilder (from searching stackoverflow of course.
)
override fun onPrepareDialogBuilder(builder: AlertDialog.Builder?) { //So can set have a button to set the default value
super.onPrepareDialogBuilder(builder)
builder?.setNeutralButton("Default") { dialogInterface: DialogInterface, i: Int ->
text = sharedPreferences.getString(dftKey, "")
}
}
However, this method does not seem possible with the androidx EditTextPreference.
Any suggestions on how to add a neutral button to androidx's EditTextPreference would be appreciated.
Having set up my settings activity as per
https://developer.android.com/guide/topics/ui/settings
I have found that I can add the PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback
interface to the AppCompatActivity and override onPreferenceDisplayDialog to show my own dialog.
Edit 15/1/23
Someone wanted to know more about fun myPrefDialog, so I have added some more code. Hope it helps. It makes it rather lengthy and not "completely complete"
class MySettingsActivity: AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceDisplayDialogCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager
.beginTransaction()
.replace(android.R.id.content, MyPreferenceFragment())
.commit()
}
override fun onPreferenceDisplayDialog(caller: PreferenceFragmentCompat, pref: Preference?): Boolean {
var handeld = false
if(pref is MyEditTextPreference) {
myPrefDialog(caller, pref)
handled = true
}
return handled
}
}
open class TlEditTextPreference: EditTextPreference {
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
constructor(context: Context) : super(context)
protected var dlgOptions = 0
internal var origTitle = title.toString()
var valueBeforeEdit: String = ""
override fun onAttached() {
super.onAttached()
PrefUtils.chkSetPrefDefault(this)
//These lines are a debug warning
dialogTitle = "Don't use default dialog."
dialogMessage = "Override onPreferenceDisplayDialog in the preference activity\n"
" to call my own dialog"
positiveButtonText = "Hey stupid, read the warning above"
}
override fun setText(text: String?) {
super.setText(text)
updateTitle()
}
fun updateTitle() {
try {
title = "$origTitle [$text]"
} catch (e: Exception) {
e.printStackTrace()
}
}
open fun myPrefDialog(context: Context): Boolean {
valueBeforeEdit = text ?: ""
dlgOptions = dlgOptions or Misc.idoSTART_SELECTED or Misc.idoDONE_KEY
val dft = PrefUtils.chkSetPrefDefault(this)
Misc.inputDlg2(context, title.toString(), "(Default $dft)",valueBeforeEdit, "Cancel", "Default", "OK", dlgOptions)
{ editText, which ->
when(which) {
Misc.BTN_POS -> text = editText.text.toString()
Misc.BTN_NEUTRAL -> text = dft
}
}
return true
}
}
const val idoNONE = 0
const val idoNO_FULLSCREEN = 1
const val idoSTART_SELECTED = 2
const val idoDONE_KEY = 4
const val idoNUMERIC_KEYPAD = 8
const val idoFIRST_LETTER_LOWERCASE = 0x10
const val idoPASSWORD = 0x20
const val idoAll_CAPS = 0x40
class inputDlg2(context: Context, title: String, msg: String, text: String, btnNeg: String?, btnNeutral: String?,
btnPos: String?, options: Int = idoNONE, dialogCallback: (editText: EditText, which: Int) -> Unit){
val inflater = LayoutInflater.from(context)
// val rv = (context as Activity).window.decorView
val rootView: ViewGroup = (context as Activity).findViewById(android.R.id.content) as ViewGroup
val promptView = inflater.inflate(R.layout.input_box, rootView, false)
val db = AlertDialog.Builder(context)
var inputDlgEditText = promptView.findViewById(R.id.edittext) as EditText
val ocListener = DialogInterface.OnClickListener { dialog, which ->
lastInputDlgText = inputDlgEditText.text.toString()
dialogCallback(inputDlgEditText, which)
}
init {
inputDlgEditText.setText(text)
inputDlgEditText.setTextIsSelectable(true)
if (options and idoNUMERIC_KEYPAD != 0) {
// inputDlgEditText.inputType = InputType.TYPE_NUMBER_FLAG_DECIMAL
// inputDlgEditText.setRawInputType(Configuration.KEYBOARD_12KEY)
inputDlgEditText.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL or InputType.TYPE_NUMBER_FLAG_SIGNED
} else
inputDlgEditText.inputType = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES or inputDlgEditText.inputType
if(options and idoPASSWORD != 0)
inputDlgEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
if (options and idoSTART_SELECTED != 0)
inputDlgEditText.setSelectAllOnFocus(true) //So that last current string will be selected and disapear if start typing
if(options and idoFIRST_LETTER_LOWERCASE != 0)
inputDlgEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
if(options and idoAll_CAPS != 0)
inputDlgEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS
if(options and idoPASSWORD != 0)
inputDlgEditText.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
var editorInfoFlags = 0
if (options and idoNO_FULLSCREEN != 0) {
inputDlgEditText.isSingleLine = true //Added in API29
editorInfoFlags = editorInfoFlags or EditorInfo.IME_FLAG_NO_FULLSCREEN //to disable full screen editor
}
if (options and idoDONE_KEY != 0)
editorInfoFlags = editorInfoFlags or EditorInfo.IME_ACTION_DONE
inputDlgEditText.imeOptions = editorInfoFlags
val message = promptView.findViewById(R.id.inputPrompt) as TextView
message.text = msg
db.setView(promptView)
db.setTitle(title)
if (btnPos != null) db.setPositiveButton(btnPos, ocListener)
if (btnNeutral != null) db.setNeutralButton(btnNeutral, ocListener)
if (btnNeg != null) db.setNegativeButton(btnNeg, ocListener)
db.setIcon(android.R.drawable.ic_dialog_alert)
val dlg = db.create()
dlg.window!!.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) //Show the software keyboard immediately
val wmlp = dlg.window!!.attributes
wmlp.gravity = Gravity.TOP or Gravity.CENTER_HORIZONTAL
wmlp.x = 0 //x position
// wmlp.y = 100; //y position
inputDlgEditText.requestFocus()
dlg.show()
inputDlgEditText.setOnTouchListener { v, event ->
val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(inputDlgEditText, 0)
false
}
if(options and idoDONE_KEY != 0) { //Callback when the done key pressed
inputDlgEditText.setOnEditorActionListener { textView: TextView?, action: Int, keyEvent: KeyEvent? ->
if (action == EditorInfo.IME_ACTION_DONE) {
dialogCallback(inputDlgEditText, Misc.BTN_POS)
dlg.dismiss()
}
false
}
}
}
}
I am new to SignalR and in the learning process, I am trying to make Stock ticker. I have over 1000 stocks list and want to show paging and update on real-time changes that's why I am using Groups with SignalR. Problem is that when I open page 1 then everything works fine until I open page 2, then page 1 stop getting signals and page 2 start getting signals. What am I missing here in SignalR groups? Please help me, Thanks.
Hub
[HubName("stockTicker")]
public class StockTickerHub : Hub
{
private StockTicker _stockTicker;
public StockTickerHub()
: this(StockTicker.Instance)
{
}
public StockTickerHub(StockTicker stockTicker)
{
_stockTicker = stockTicker;
}
public void OpenMarket()
{
var page = this.Context.QueryString["page_no"];
int pageno = Convert.ToInt32(page);
_stockTicker.OpenMarket(pageno);
tryAddGroup(page);
}
public Task tryAddGroup(string page)
{
return Groups.Add(Context.ConnectionId, page);
}
}
StockTicker.cs
public class StockTicker
{
MainModel _model = new MainModel();
private static Lazy<StockTicker> _instance = new Lazy<StockTicker>(() => new StockTicker(GlobalHost.ConnectionManager.GetHubContext<StockTickerHub>().Clients));
private TimeSpan _updateInterval = TimeSpan.FromMilliseconds(3000);
private Timer _timer;
public volatile int pageno;
private StockTicker(IHubConnectionContext<dynamic> clients)
{
Clients = clients;
}
public static StockTicker Instance
{
get
{
return _instance.Value;
}
}
private IHubConnectionContext<dynamic> Clients
{
get;
set;
}
public void OpenMarket(int page_no)
{
pageno = page_no;
_timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
}
private void UpdateStockPrices(object state)
{
var latest_stocks = new List<StockViewModel>();
latest_stocks = _model.Get100Stocks(pageno);
foreach (var stock in latest_stocks)
{
BroadcastStockPrice(stock, pageno);
}
}
private void BroadcastStockPrice(StockViewModel stock, int pageno)
{
Clients.Group(pageno.ToString()).updateStockPrice(stock);
//Clients.All.updateStockPrice(stock);
}
}
(Updated Question)
StockTicker.js
if (!String.prototype.supplant) {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
jQuery.fn.flash = function (color, duration) {
var current = this.css('backgroundColor');
this.animate({ backgroundColor: 'rgb(' + color + ')' }, duration / 2)
.animate({ backgroundColor: current }, duration / 2);
};
$(function () {
var ticker = $.connection.stockTicker;
var $stockTable = $('#stockTable');
var $stockTableBody = $stockTable.find('tbody');
tdPrice = '<td data-rank-price="{currency_query}" data-sort="{currency_price_usd}"><div data-price-spn="{currency_query}">${currency_price_usd}</div></td>';
tdPercentage = '<td data-rank-perc="{currency_query}" data-sort="{currency_change_24h_usd}"><div data-change-spn="{currency_query}"><span class="{DirectionClass}">{currency_change_24h_usd}</span></div></td>';
tdVolume = '<td data-rank-volume="{currency_query}" data-sort="{currency_24h_volume_usd}"><div data-24-volume-spn="{currency_query}>${currency_24h_volume_usd}</div></td>';
tdMarketcap = '<td data-rank-cap="{currency_query}" data-sort="{currency_market_cap_usd}"><div data-mcap-spn="{currency_query}">${currency_market_cap_usd}</div></td>';
function formatStock(stock) {
return $.extend(stock, {
currency_price_usd: formatprices(stock.currency_price_usd),
currency_change_24h_usd: stock.currency_change_24h_usd == null ? '0.00%' : (stock.currency_change_24h_usd).toFixed(2) + '%',
currency_24h_volume_usd: stock.currency_24h_volume_usd == null ? '0' : nFormatter(stock.currency_24h_volume_usd, 2),
currency_market_cap_usd: stock.currency_market_cap_usd == null ? '0' : nFormatter(stock.currency_market_cap_usd, 2),
DirectionClass: stock.currency_change_24h_usd === 0 ? 'nochange' : stock.currency_change_24h_usd >= 0 ? 'green' : 'red'
});
}
function nFormatter(num, digits) {
var si = [
{ value: 1, symbol: "" },
{ value: 1E3, symbol: "K" },
{ value: 1E6, symbol: "M" },
{ value: 1E9, symbol: "B" },
{ value: 1E12, symbol: "T" },
{ value: 1E15, symbol: "P" },
{ value: 1E18, symbol: "E" }
];
var rx = /\.0+$|(\.[0-9]*[1-9])0+$/;
var i;
for (i = si.length - 1; i > 0; i--) {
if (num >= si[i].value) {
break;
}
}
return (num / si[i].value).toFixed(digits).replace(rx, "$1") + si[i].symbol;
}
function formatprices(n, curr) {
var sep = sep || ".";
var decimals;
if (n > 0.99999999) {
decimals = decimals || 2;
}
else {
decimals = decimals || 6;
}
return n.toLocaleString().split(sep)[0]
+ sep
+ n.toFixed(decimals).split(sep)[1];
}
$.extend(ticker.client, {
updateStockPrice: function (stock) {
var displayStock = formatStock(stock),
$tdprice = $(tdPrice.supplant(displayStock)),
$tdpercentage = $(tdPercentage.supplant(displayStock)),
$tdvolume = $(tdVolume.supplant(displayStock)),
$tdcap = $(tdMarketcap.supplant(displayStock));
if (stock.LastChange != 0.0) {
bgprice = stock.LastChange < 0.0
? '255,148,148'
: '154,240,117';
$stockTableBody.find('td[data-rank-price=' + stock.currency_query + ']').replaceWith($tdprice);
$tdpricespn = $stockTableBody.find('div[data-price-spn=' + stock.currency_query + ']');
$tdpricespn.flash(bgprice, 1500);
}
if (stock.LastChangePercentage != 0.0) {
bgper = stock.LastChangePercentage < 0.0
? '255,148,148'
: '154,240,117';
$stockTableBody.find('td[data-rank-perc=' + stock.currency_query + ']').replaceWith($tdpercentage);
$tdpercentagespn = $stockTableBody.find('div[data-change-spn=' + stock.currency_query + ']');
$tdpercentagespn.flash(bgper, 1500);
}
if (stock.LastChangeVolume != 0.0) {
bgvol = stock.LastChangeVolume < 0.0
? '255,148,148'
: '154,240,117';
$stockTableBody.find('td[data-rank-volume=' + stock.currency_query + ']').replaceWith($tdvolume);
$tdvolumespn = $stockTableBody.find('div[data-24-volume-spn=' + stock.currency_query + ']');
$tdvolumespn.flash(bgvol, 1500);
}
if (stock.LastChangeCap != 0.0) {
bgcap = stock.LastChangeCap < 0.0
? '255,148,148'
: '154,240,117';
$stockTableBody.find('td[data-rank-cap=' + stock.currency_query + ']').replaceWith($tdcap);
$tdcapspn = $stockTableBody.find('div[data-mcap-spn=' + stock.currency_query + ']');
$tdcapspn.flash(bgcap, 1500);
}
}
});
$.connection.hub.url = 'http://localhost:13429/signalr';
$.connection.hub.qs = { 'page_no': $("#page").val() };
$.connection.hub.start().done(function () {
console.log("connected");
}).then(function () {
return ticker.server.openMarket();
});
});
Looking at your code, your global variable pageno is always the last page that was requested:
public void OpenMarket(int page_no)
{
pageno = page_no;
_timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
}
You need another variable that tracks the max page.
public volatile int pageMax;
public void OpenMarket(int page_no)
{
pageno = page_no;
pageMax = pageno > pageMax
: pageno
? pageMax;
_timer = new Timer(UpdateStockPrices, pageno, _updateInterval, _updateInterval);
}
Then make sure to broadcast the correct stocks to the pages.
I am using the Yalantis filter for android. I am having a Fragment rather than activity :
`class IncentiveActivity :Fragment() , FilterListener {
private var incentiveList = ArrayList<Incentive>()
var mAdapter: IncentiveListRecyclerAdapter? = null
val handler: Handler by lazy {
Handler()
}
private var mColors: IntArray? = null
private var mTitles: Array<String>? = null
private var mAllQuestions: List<Incentive>? = null
private var mFilter: Filter<FilterTag>? = null
val that :Context? = null
var fragment : View? =null
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
fragment = inflater!!.inflate(R.layout.activity_incentive_detail, container, false)
return fragment
}
override fun onStart() {
super.onStart()
setIncentiveAdapter()
mColors = getResources().getIntArray(R.array.colorslist);
mTitles = getResources().getStringArray(R.array.job_titles);
mFilter = this.filter as Filter<FilterTag>
mFilter!!.adapter =Adapter(getTags())
mFilter!!.listener = this
//the text to show when there's no selected items
mFilter!!.noSelectedItemText = getString(R.string.str_all_selected)
mFilter!!.build()
}
private fun getTags():List<FilterTag> {
val tags = ArrayList<FilterTag>()
for (i in 0..mTitles!!.size - 1) {
tags.add(FilterTag(mTitles!![i], mColors!![i]))
}
return tags
}
fun setIncentiveAdapter(){
//todo for salafi API call here and set adapter
val in1 = Incentive("Get 100p by completing 10","Description","D","Cash","100","ACTIVE",10,"id-vcxsdt","ACTIVE",8,6,9)
val in2 = Incentive("Get 100p by completing 10","Description","W","Cash","100","OPTED",10,"id-vcxsdt","OPTED",8,6,9)
val in3 = Incentive("Get 100p by completing 10","Description","Y","Cash","100","EXPIRED",10,"id-vcxsdt","EXPIRED",8,6,9)
val in4 = Incentive("Get 100p by completing 10","Description","Y","Cash","100","ACHIEVED",10,"id-vcxsdt","EXPIRED",8,6,9)
val in5 = Incentive("Get 100p by completing 10","Description","Y","Cash","100","NOT_OPTED",10,"id-vcxsdt","NOT_OPTED",8,6,9)
incentiveList.add(in1)
incentiveList.add(in2)
incentiveList.add(in3)
incentiveList.add(in4)
incentiveList.add(in5)
mAdapter = IncentiveListRecyclerAdapter(context, incentiveList)
incentiveListView.adapter = mAdapter
incentiveListView.layoutManager = LinearLayoutManager(context)
}
private fun calculateDiff(oldList: List<Incentive>, newList: List<Incentive >) {
DiffUtil.calculateDiff(object : DiffUtil.Callback() {
override fun getOldListSize(): Int {
return oldList.size
}
override fun getNewListSize(): Int {
return newList.size
}
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].equals(newList[newItemPosition])
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
return oldList[oldItemPosition].equals(newList[newItemPosition])
}
}).dispatchUpdatesTo(mAdapter)
}
override fun onFilterDeselected(item: FilterTag) {
}
override fun onFilterSelected(item: FilterTag) {
Log.e("Item",item.getText())
if (item.getText().equals(mTitles!![0])) {
Log.e("mtitle",mTitles!![0])
mFilter!!.deselectAll();
mFilter!!.collapse();
}
}
/*private fun findByTags(tags: List<FilterTag>): List<Incentive> {
val questions = ArrayList<Incentive>()
for (question in mAllQuestions!!) {
for (tag in tags) {
if (question.hasTag(tag.getText()) && !questions.contains(question)) {
questions.add(question)
}
}
}
return questions
}*/
override fun onFiltersSelected(filters: java.util.ArrayList<FilterTag>) {
Log.e("filter",filters.size.toString())
/*val newQuestions = findByTags(filters)
val oldQuestions = mAdapter.getQuestions()
mAdapter.setQuestions(newQuestions)
calculateDiff(oldQuestions, newQuestions)*/
}
override fun onNothingSelected() {
if (this.incentiveListView != null) {
mFilter!!.adapter =Adapter(getTags())
incentiveListView.adapter = mAdapter
}
}
inner class Adapter(#NotNull items: List<FilterTag>) : FilterAdapter<FilterTag>(items) {
override fun createView(position: Int, item: FilterTag): FilterItem {
val filterItem = FilterItem(this#IncentiveActivity.activity)
filterItem.strokeColor = mColors!![0]
filterItem.textColor = mColors!![0]
filterItem.cornerRadius = 14f
filterItem.checkedTextColor = ContextCompat.getColor(this#IncentiveActivity.activity, android.R.color.white)
filterItem.color = ContextCompat.getColor(this#IncentiveActivity.activity, R.color.m_color2)
filterItem.checkedColor = mColors!![position]
filterItem.text = item.getText()
filterItem.deselect()
return filterItem
}
}
}`
i am facing problem when i expand the filter it comes in background of my list keeping my list visible .
this is my listView when i first open the fragment
this is the listview after i select the filter
also i am sorry if i have not provided all details and my question doesn't follow the SOF conditions thank you
I am trying to query data from orientdb while ignoring some edges.
My query has the form:
select expand(dijkstra(#12:15,#12:20,'property','both'))
but as mentioned I want to ignore some edges of the graph.
Are there any suggestions?
Edit
Here is my graph structure .
Station as Vertex
Image Click
Path as Edge
Image Click
Thank you #Ivan Mainetti so much for answer i have try the testing main()
Here is my main()
String nomeDb = "Demo2";
try {
System.out.println("Before connect OServerAdmin");
OServerAdmin serverAdmin = new OServerAdmin("remote:128.199.xxx.xxx/"+nomeDb).connect("admin","password");
System.out.println("After connect");
if(serverAdmin.existsDatabase()){ // il db esiste
System.out.println("in if");
//connessione a db
OrientGraph g = new OrientGraph("remote:128.199.xxx.xxx/"+nomeDb);
DijkstraExcl d = new DijkstraExcl(g, "Path", "distance");
Set<String> ex =new HashSet<String>();
//------------------------------------------------
Vertex start = g.getVertex("#12:6");
Vertex end = g.getVertex("#12:11");
ex.add("#13:0");
Direction direction = Direction.OUT;
System.out.println(d.getPath(start,end,direction,ex));
System.out.println(d.getPathString(start,end,direction,ex));
System.out.println(d.getWeight(start,end,direction,ex));
//------------------------------------------------
//chiude db
g.shutdown();
}
else{
System.out.println("Il database '"+ nomeDb + "' non esiste");
}
serverAdmin.close();
} catch (IOException e) {
e.printStackTrace();
}
and the result after run the main() is
null
null
2147483647
The correct answer after ignore [#13:0] should be
[#12:6,#12:8,#12:10,#12:11]
Try the following JS function that has as parameters ridFrom, ridTo, property, direction and excludeEdges.
With Studio you can try it with this command:
select expand(result) from (select myFunction("12:6","12:11","distance","out","[#13:0]") as result)
The edges "edge1" and "edge2" are ignored.
var g=orient.getGraph();
var listEdges=excludeEdges.substring(1,excludeEdges.length-1).split(",");
var S=[], T=[] , id_weigth=[] , from , to , infinity = Number.MAX_VALUE;
step1();
step2();
return getPath();
// Initialization
function step1() {
var selectFrom=g.command("sql","select from V where #rid ="+ ridFrom);
var selectTo=g.command("sql","select from V where #rid ="+ ridTo);
if(selectFrom.length>0 && selectTo.length>0){
from=selectFrom[0];
to=selectTo[0];
S.push(from);
var selectAll=g.command("sql","select from V");
for (i=0;i<selectAll.length;i++) {
if (selectAll[i].getId()!=from.getId())
T.push(selectAll[i]);
}
var index=1;
for (i=0;i<selectAll.length;i++) {
var id = selectAll[i].getId();
if (selectAll[i].getId()!= from.getId()) {
id_weigth[index] = {id:id,weigth:infinity};
index++;
}
else
id_weigth[0] = {id:id,weigth:0};
}
setWeigth_Direction(from);
}
}
// Assignment permanent label
function step2(){
var stop = true;
do {
stop = true;
for (i=0;i<T.length;i++) {
var id = T[i].getId();
for (j=0;j<id_weigth.length;j++) {
if (id_weigth[j].id==id) {
if (id_weigth[j].weigth != infinity){
stop = false;
}
}
}
}
if (stop == true)
break;
else {
var index2 = 0; minWeigth = 0; j = null;
for (i=0;i<T.length;i++) {
var id = T[i].getId();
for (m=0;m<id_weigth.length;m++) {
if (id_weigth[m].id==id) {
if (index2 == 0) {
minWeigth = id_weigth[m].weigth;
index2++;
j = T[i];
}
else if (id_weigth[m].weigth < minWeigth) {
minWeigth = id_weigth[m].weigth;
j = T[i];
}
}
}
}
T.splice(getPositionInT(j.getId()),1);
S.push(j);
if (T.length == 0)
break;
else
step3(j);
}
} while (stop == false);
}
// Assignment temporary label
function step3(j) {
setWeigth_Direction(j);
}
function setWeigth(vertex,direction1,direction2) {
var edges=g.command("sql","select expand(" + direction1+"E()) from "+ vertex.getId());
for(m=0;m<edges.length;m++){
var myEdge=edges[m];;
var idEdge = myEdge.getId().toString();
var validEdge=true;
for (s=0;s<listEdges.length;s++) {
if(listEdges[s]==idEdge)
validEdge=false;
}
if(validEdge==true){
var myWeigth = myEdge.getProperty(property);
var myVertex=g.command("sql","select expand("+ direction2 + ") from " +myEdge.getId());
var id = myVertex[0].getId();
if(vertex!=from){
for (p=0;p<T.length;p++) {
if (T[p].getId()==id) {
var id_weight_i = getId_Weigth(id);
var id_weight_j = getId_Weigth(j.getId());
var weigthi = id_weight_i.weigth;
var weigthj = id_weight_j.weigth;
if (weigthi > weigthj + myWeigth) {
id_weight_i.weigth=weigthj + myWeigth;
id_weight_i.previous=vertex;
}
}
}
}
else{
for (q=0;q<id_weigth.length;q++) {
if (id_weigth[q].id==id) {
id_weigth[q].weigth=myWeigth;
id_weigth[q].previous=vertex;
}
}
}
}
}
}
function getId_Weigth(id) {
for (l=0;l<id_weigth.length;l++) {
if (id_weigth[l].id==id)
return id_weigth[l];
}
return null;
}
function getPath(){
var validPath = true, temp = [], path = [];
temp.push(to);
var npm = getId_Weigth(to.getId());
var v = npm.previous;
while (v != from) {
temp.push(v);
if (v == null) {
validPath = false;
break;
}
npm = getId_Weigth(v.getId());
v = npm.previous;
}
if (validPath == true) {
temp.push(from);
for (i = temp.length - 1; i >= 0; i--)
path.push(temp[i]);
}
return path;
}
function setWeigth_Direction(vertex){
if (direction == "both"){
setWeigth(vertex,"in","out");
setWeigth(vertex,"out","in");
}
else if (direction == "in")
setWeigth(vertex,"in","out");
else
setWeigth(vertex,"out","in");
}
function getPositionInT(id){
for (l=0;l<T.length;l++) {
if(T[l].getId()==id)
return l;
}
return null;
}
I created this class that find the dijkstra path including the option of excluding a specific list of edges by rid number.
DijkstraExcl.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.tinkerpop.blueprints.Direction;
import com.tinkerpop.blueprints.Edge;
import com.tinkerpop.blueprints.Vertex;
import com.tinkerpop.blueprints.impls.orient.OrientGraph;
public class DijkstraExcl {
private OrientGraph g; //grafh DB
private Set<String> S; //visited rids
private Set<String> T; //to visit rids
private Map<String,Integer> f; //f(i) < #rid, weight_to_get_to_#rid >
private Map<String,String> J; //J(i) < #rid, previous_node_in_the_shortest_path >
private String eClass; //edge class to use
private String prop; //weight property to use on the edge
public DijkstraExcl(OrientGraph g, String e, String p){
this.g= g;
this.eClass = e;
this.prop = p;
S = new HashSet<String>();
T = new HashSet<String>();
f = new HashMap<String,Integer>();
J = new HashMap<String,String>();
}
//private methods
// (Vertex start_vertex, Vertex dest_vertex, Direction.IN/OUT/BOTH, Set of edge rids to exclude)
private void findPath(Vertex startV, Vertex endV, Direction dir, Set<String> excludeEdgeRids){
//init
S.clear();
T.clear();
f.clear();
J.clear();
//step1
Iterator<Vertex> vertici = g.getVertices().iterator();
while(vertici.hasNext()){
Vertex ver = vertici.next();
f.put(ver.getId().toString(), Integer.MAX_VALUE);
T.add(ver.getId().toString());
}
f.put(startV.getId().toString(), 0); //f(startV) = 0
J.put(startV.getId().toString(), null); //J(startV) = null
T.remove(startV.getId().toString()); //startV visited => removed from T
S.add(startV.getId().toString()); // and added in S
Iterator<Vertex> near = startV.getVertices(dir, eClass).iterator();
while(near.hasNext()){
Vertex vicino = near.next();
J.put(vicino.getId().toString(), startV.getId().toString()); //J(i) = startV
f.put(vicino.getId().toString(), weight(startV.getId().toString(), vicino.getId().toString(),dir,excludeEdgeRids)); //f(i) = weight(startV, i)
}
//step2
Boolean cont = false;
Iterator<String> t = T.iterator();
while(t.hasNext()){
String i = t.next();
if(f.get(i)!=Integer.MAX_VALUE){
cont = true;
}
}
while(cont){
String j = startV.getId().toString();
Integer ff = Integer.MAX_VALUE;
t = T.iterator();
while(t.hasNext()){
String i = t.next();
if(f.get(i)<=ff){
ff = f.get(i);
j = i;
}
}
T.remove(j);
S.add(j);
if(T.isEmpty()){
break;
}
//step3
near = g.getVertex(j).getVertices(dir, eClass).iterator();
while(near.hasNext()){
Vertex vic = near.next();
String i = vic.getId().toString();
if( (T.contains(i)) && (f.get(i) > (f.get(j) + weight(j,i,dir,excludeEdgeRids))) ){
if(weight(j,i,dir,excludeEdgeRids)==Integer.MAX_VALUE){
f.put(i, Integer.MAX_VALUE);
}else{
f.put(i, (f.get(j) + weight(j,i,dir,excludeEdgeRids)));
}
J.put(i, j);
}
}
//shall we continue?
cont = false;
t = T.iterator();
while(t.hasNext()){
String i = t.next();
if(f.get(i)!=Integer.MAX_VALUE){
cont = true;
}
}
}
}
private int weight(String rid_a, String rid_b, Direction dir, Set<String> excl){ //in case of multiple/duplicate edges return the lightest
Integer d = Integer.MAX_VALUE;
Integer dd;
rid_b = "v["+rid_b+"]";
if(excl==null){
excl = new HashSet<String>();
}
Vertex a = g.getVertex(rid_a);
Iterator<Edge> eS = a.getEdges(dir, eClass).iterator();
Set<Edge> goodEdges = new HashSet<Edge>();
while(eS.hasNext()){
Edge e = eS.next();
if((e.getProperty("out").toString().equals(rid_b) || e.getProperty("in").toString().equals(rid_b)) && !excl.contains(e.getId().toString())){
goodEdges.add(e);
}
}
Iterator<Edge> edges= goodEdges.iterator();
while(edges.hasNext()){
Edge e=edges.next();
dd = e.getProperty(prop);
if(dd<d){
d=dd;
}
}
return d;
}
//public methods
public List<Vertex> getPath (Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
String j,i;
List<Vertex> ppp = new ArrayList<Vertex>();
List<Vertex> path = new ArrayList<Vertex>();
findPath(startV, endV, dir, exclECl);
i = endV.getId().toString();
path.add(endV);
if(f.get(endV.getId().toString()) == Integer.MAX_VALUE){
return null;
}
while(!i.equals(startV.getId().toString())){
j = J.get(i);
if(j == null){
return null;
}
path.add(g.getVertex(j));
i = j;
}
for(int a=0, b=path.size()-1;a<path.size();a++, b--){
ppp.add(a, path.get(b));
}
return ppp;
}
public List<String> getPathString (Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
List<String> pathS = new ArrayList<String>();
List<Vertex> path = getPath(startV, endV, dir, exclECl);
if(path == null){
return null;
}
for(Vertex v : path){
pathS.add(v.getId().toString());
}
return pathS;
}
public Integer getWeight(Vertex startV, Vertex endV, Direction dir, Set<String> exclECl){
findPath(startV, endV, dir,exclECl);
return f.get(endV.getId().toString());
}
}
and hers's a testing main:
public class test_dijkstra {
public static void main(String[] args) {
String nomeDb = "dijkstra_test";
try {
OServerAdmin serverAdmin = new OServerAdmin("remote:localhost/"+nomeDb).connect("root", "root");
if(serverAdmin.existsDatabase()){ // il db esiste
//connessione a db
OrientGraph g = new OrientGraph("remote:localhost/"+nomeDb);
DijkstraExcl d = new DijkstraExcl(g, "arco", "peso");
Set<String> ex =new HashSet<String>();
//------------------------------------------------
Vertex start = g.getVertex("#9:0");
Vertex end = g.getVertex("#9:5");
ex.add("#12:4");
Direction direction = Direction.BOTH;
System.out.println(d.getPath(start,end,direction,ex));
System.out.println(d.getPathString(start,end,direction,ex));
System.out.println(d.getWeight(start,end,direction,ex));
//------------------------------------------------
//chiude db
g.shutdown();
}
else{
System.out.println("Il database '"+ nomeDb + "' non esiste");
}
serverAdmin.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and its output:
[v[#9:0], v[#9:1], v[#9:2], v[#9:4], v[#9:5]]
[#9:0, #9:1, #9:2, #9:4, #9:5]
10
Here's the structure of my test db:
One approach would be to use the fact that OrientDB has some support for "Infinity", as illustrated by this "console.sh" typescript:
> select 1.0E400
----+------+--------
# |#CLASS|1
----+------+--------
0 |null |Infinity
----+------+--------
> select eval('0 < 1.0E400')
----+------+----
# |#CLASS|eval
----+------+----
0 |null |true
----+------+----
> select -1.0E400
----+------+---------
# |#CLASS|-1
----+------+---------
0 |null |-Infinity
----+------+---------
> select eval('0 < -1.0E400')
----+------+-----
# |#CLASS|eval
----+------+-----
0 |null |false
----+------+-----