问:
rmagick under windows
I just wanted to install rmagick under windows.

So I installed ImageMagick with C/C++ header, but that seems no more to be necessary.

Then I installed the Ruby Build Tools

```<code>ruby dk.rb init
ruby dk.rb install
</code>```

Then I wanted to install the rmagick gem with gem install rmagick.

But I get this error:

```<code>H:\Downloads\ruby build tools>gem install rmagick
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
        ERROR: Failed to build gem native extension.

        C:/Ruby192/bin/ruby.exe extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=C:/Ruby192/bin/ruby
C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:368:in `try_do': The complier failed to generate
an executable file. (RuntimeError)
You have to install development tools first.
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:452:in `try_cpp'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:834:in `block in have_header'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:693:in `block in checking_for'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:280:in `block (2 levels) in postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:254:in `open'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:280:in `block in postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:254:in `open'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:276:in `postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:692:in `checking_for'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:833:in `have_header'
        from extconf.rb:193:in `<main>'

Gem files will remain installed in C:/Ruby192/lib/ruby/gems/1.9.1/gems/rmagick-2.13.1
for inspection.
Results logged to C:/Ruby192/lib/ruby/gems/1.9.1/gems/rmagick-2.13.1/ext/RMagick/gem_make.out
</code>```

Before I installed the Build Tools, I just got the advice to install them.

Now they are installed and I get a different error message than before (see above).

It still wants me to install the Build Tools, so its installation might be broken?

I get the same error with linecache... also something with the mkmf file and build tools.

I guess this is a common error.

答:
Include the head files & lib files to your System Environment first:

```<code>set CPATH=C:/Progra~2/ImageMagick-6.7.0-Q16/include
set LIBRARY_PATH=C:/Progra~2/ImageMagick-6.7.0-Q16/lib
</code>```

Them, gem install ** will be done.
~.~

Title: rmagick under windows

Body:
I just wanted to install rmagick under windows.

So I installed ImageMagick with C/C++ header, but that seems no more to be necessary.

Then I installed the Ruby Build Tools

ruby dk.rb init
ruby dk.rb install

Then I wanted to install the rmagick gem with gem install rmagick.

But I get this error:

H:\Downloads\ruby build tools>gem install rmagick
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing rmagick:
        ERROR: Failed to build gem native extension.

        C:/Ruby192/bin/ruby.exe extconf.rb
checking for Ruby version >= 1.8.5... yes
checking for stdint.h... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=C:/Ruby192/bin/ruby
C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:368:in `try_do': The complier failed to generate
an executable file. (RuntimeError)
You have to install development tools first.
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:452:in `try_cpp'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:834:in `block in have_header'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:693:in `block in checking_for'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:280:in `block (2 levels) in postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:254:in `open'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:280:in `block in postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:254:in `open'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:276:in `postpone'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:692:in `checking_for'
        from C:/Ruby192/lib/ruby/1.9.1/mkmf.rb:833:in `have_header'
        from extconf.rb:193:in `'

Gem files will remain installed in C:/Ruby192/lib/ruby/gems/1.9.1/gems/rmagick-2.13.1
for inspection.
Results logged to C:/Ruby192/lib/ruby/gems/1.9.1/gems/rmagick-2.13.1/ext/RMagick/gem_make.out

Before I installed the Build Tools, I just got the advice to install them.

Now they are installed and I get a different error message than before (see above).

It still wants me to install the Build Tools, so its installation might be broken?

I get the same error with linecache... also something with the mkmf file and build tools.

I guess this is a common error.

Body:
Include the head files & lib files to your System Environment first:

set CPATH=C:/Progra~2/ImageMagick-6.7.0-Q16/include
set LIBRARY_PATH=C:/Progra~2/ImageMagick-6.7.0-Q16/lib

Them, gem install ** will be done.
~.~


来源: stackexchange

问:
Android Studio - findViewById() causing error
This is my first post so apologies if I get any of the formalities wrong...

Before anyone tells me the question is invalid, every solution I have looked at says I should have:

```<code>setContentView(R.layout.whateverViewImCurrentlyTryingToFocus)
</code>```

before I call a

```<code>findViewById()
</code>```

When I debug my application it is crashing when I set up an onClickListener for my button (R.id.sign_in_button), line 75.

So I decided to check what findViewById() was returning so I run the code

```<code>Button button = findViewById(R.id.sign_in_button)
</code>```

This caused the same error. I think it it returning null but not entirely sure.

Activitylogin.xml is the first layout to be loaded, and then the mainactivity.xml is supposed to launch after a firebase sign-in.

Java code:

LoginActivity.java

```<code>package com.styryl.socials.ui.login;

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.styryl.socials.MainActivity;
import com.styryl.socials.R;
import com.styryl.socials.ui.login.LoginViewModel;
import com.styryl.socials.ui.login.LoginViewModelFactory;

public class LoginActivity extends AppCompatActivity {

    private LoginViewModel loginViewModel;
    private FirebaseAuth mAuth;
    private GoogleSignInClient mGoogleSignInClient;
    private final static int RC_SIGN_IN = 1;
    private String TAG = "Login Activity";

    @Override
    protected void onStart() {
        super.onStart();

        FirebaseUser user = mAuth.getCurrentUser();

        if(user != null){
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(intent);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        mAuth = FirebaseAuth.getInstance();

        createRequest();

        // Button findViewByID returns null
        findViewById(R.id.sign_in_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signIn();
            }
        });
        }

    private void createRequest() {
        // Configure Google Sign In
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();

        // Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    }

    private void signIn() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
                firebaseAuthWithGoogle(account.getIdToken());
            } catch (ApiException e) {
                // Google Sign In failed, update UI appropriately
                Log.w(TAG, "Google sign in failed", e);
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
                // ...
            }
        }
    }

    private void firebaseAuthWithGoogle(String idToken) {
        AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInWithCredential:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                            startActivity(intent);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(LoginActivity.this, "Authentication Failed.", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
}
</code>```

MainActivity.java

```<code>package com.styryl.socials;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.firebase.auth.FirebaseAuth;
import com.styryl.socials.ui.login.LoginActivity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

public class MainActivity extends AppCompatActivity {

    TextView user_username;
    TextView user_email;

    Button logout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        user_username = findViewById(R.id.user_username);
        user_email = findViewById(R.id.user_email);
        logout = findViewById(R.id.logout_button);

        BottomNavigationView navView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_profile)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navView, navController);

        GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);
        if(signInAccount != null){
            user_username.setText(signInAccount.getDisplayName());
            user_email.setText(signInAccount.getEmail());
        }

        logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseAuth.getInstance().signOut();
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
            }
        });
    }

}
</code>```

Layout Files:

LoginActivity.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".ui.login.LoginActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/status_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:layout_width="110dp"
            android:layout_height="wrap_content"
            android:text="Sign Out"
            android:id="@+id/sign_out_button" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

MainActivity.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorDarkGrey"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        app:itemIconTint="@drawable/bottom_navigation_selector"
        app:itemTextColor="@drawable/bottom_navigation_selector"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>
</code>```

If you need anymore information please let me know and I will provide. I can't wrap my head around this issue and really hope some android studio experts can explain it to me as if I'm a idiot because I would love to learn!

I am attempting to fix this as soon as I wake up, because I never quit!

答:
All,

Thank you for your replies,

I woke up this morning and after looking at the logcat as suggested by @Frank van puffelen, I noticed that the error was a nullPointerException on a textView. This was weird becuase there was no textView in my loginActivity. Upon further inspection, I hadn't created the username and the email textView in my main_activity.xml (Problem with late night coding, I should have spotted that). So this was returning a nullPointerException simply because it didn't exist. I added the username, email and logout button to the xml and it works.

Thanks for the help, not entirely sure how to close this thread (this is my first post), apologies for wasting time but I was a little desperate.

ContentLicense: CC BY-SA 4.0

Body:
This is my first post so apologies if I get any of the formalities wrong...

Before anyone tells me the question is invalid, every solution I have looked at says I should have:

setContentView(R.layout.whateverViewImCurrentlyTryingToFocus)

before I call a

findViewById()

When I debug my application it is crashing when I set up an onClickListener for my button (R.id.sign_in_button), line 75.

So I decided to check what findViewById() was returning so I run the code

Button button = findViewById(R.id.sign_in_button)

This caused the same error. I think it it returning null but not entirely sure.

Activitylogin.xml is the first layout to be loaded, and then the mainactivity.xml is supposed to launch after a firebase sign-in.

Java code:

LoginActivity.java

package com.styryl.socials.ui.login;

import android.app.Activity;

import androidx.annotation.NonNull;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;

import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import androidx.appcompat.app.AppCompatActivity;

import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.snackbar.Snackbar;
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GoogleAuthProvider;
import com.styryl.socials.MainActivity;
import com.styryl.socials.R;
import com.styryl.socials.ui.login.LoginViewModel;
import com.styryl.socials.ui.login.LoginViewModelFactory;

public class LoginActivity extends AppCompatActivity {

    private LoginViewModel loginViewModel;
    private FirebaseAuth mAuth;
    private GoogleSignInClient mGoogleSignInClient;
    private final static int RC_SIGN_IN = 1;
    private String TAG = "Login Activity";

    @Override
    protected void onStart() {
        super.onStart();

        FirebaseUser user = mAuth.getCurrentUser();

        if(user != null){
            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
            startActivity(intent);
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        mAuth = FirebaseAuth.getInstance();

        createRequest();

        // Button findViewByID returns null
        findViewById(R.id.sign_in_button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                signIn();
            }
        });
        }

    private void createRequest() {
        // Configure Google Sign In
        GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                .requestIdToken(getString(R.string.default_web_client_id))
                .requestEmail()
                .build();

        // Build a GoogleSignInClient with the options specified by gso.
        mGoogleSignInClient = GoogleSignIn.getClient(this, gso);
    }

    private void signIn() {
        Intent signInIntent = mGoogleSignInClient.getSignInIntent();
        startActivityForResult(signInIntent, RC_SIGN_IN);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // Result returned from launching the Intent from GoogleSignInApi.getSignInIntent(...);
        if (requestCode == RC_SIGN_IN) {
            Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
            try {
                // Google Sign In was successful, authenticate with Firebase
                GoogleSignInAccount account = task.getResult(ApiException.class);
                Log.d(TAG, "firebaseAuthWithGoogle:" + account.getId());
                firebaseAuthWithGoogle(account.getIdToken());
            } catch (ApiException e) {
                // Google Sign In failed, update UI appropriately
                Log.w(TAG, "Google sign in failed", e);
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
                // ...
            }
        }
    }

    private void firebaseAuthWithGoogle(String idToken) {
        AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null);
        mAuth.signInWithCredential(credential)
                .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                    @Override
                    public void onComplete(@NonNull Task<AuthResult> task) {
                        if (task.isSuccessful()) {
                            // Sign in success, update UI with the signed-in user's information
                            Log.d(TAG, "signInWithCredential:success");
                            FirebaseUser user = mAuth.getCurrentUser();
                            Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                            startActivity(intent);
                        } else {
                            // If sign in fails, display a message to the user.
                            Log.w(TAG, "signInWithCredential:failure", task.getException());
                            Toast.makeText(LoginActivity.this, "Authentication Failed.", Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }
}

MainActivity.java

package com.styryl.socials;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.firebase.auth.FirebaseAuth;
import com.styryl.socials.ui.login.LoginActivity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;

public class MainActivity extends AppCompatActivity {

    TextView user_username;
    TextView user_email;

    Button logout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        user_username = findViewById(R.id.user_username);
        user_email = findViewById(R.id.user_email);
        logout = findViewById(R.id.logout_button);

        BottomNavigationView navView = findViewById(R.id.nav_view);
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
                R.id.navigation_home, R.id.navigation_dashboard, R.id.navigation_profile)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
        NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
        NavigationUI.setupWithNavController(navView, navController);

        GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);
        if(signInAccount != null){
            user_username.setText(signInAccount.getDisplayName());
            user_email.setText(signInAccount.getEmail());
        }

        logout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                FirebaseAuth.getInstance().signOut();
                Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
                startActivity(intent);
            }
        });
    }

}

Layout Files:

LoginActivity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".ui.login.LoginActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/status_textview"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" />
        <com.google.android.gms.common.SignInButton
            android:id="@+id/sign_in_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <Button
            android:layout_width="110dp"
            android:layout_height="wrap_content"
            android:text="Sign Out"
            android:id="@+id/sign_out_button" />
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorDarkGrey"
    android:paddingTop="?attr/actionBarSize">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimaryDark"
        app:itemIconTint="@drawable/bottom_navigation_selector"
        app:itemTextColor="@drawable/bottom_navigation_selector"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />

</androidx.constraintlayout.widget.ConstraintLayout>

If you need anymore information please let me know and I will provide. I can't wrap my head around this issue and really hope some android studio experts can explain it to me as if I'm a idiot because I would love to learn!

I am attempting to fix this as soon as I wake up, because I never quit!


问:
How to calculate totals in dataframe by pandas
I have got this dataframe:

```<code>Date Trader1 Trader2 Trader3
01/04/2020  4   6   8
02/04/2020  4   6   8
03/04/2020  4   7   8
04/04/2020  4   7   8
05/04/2020  3   5   7
06/04/2020  2   4   7
07/04/2020  2   3   6
08/04/2020  3   3   6
09/04/2020  3   5   7
10/04/2020  3   5   7
11/04/2020  3   5   6
</code>```

I would like to get Totals for each column by using python/pandas library. When I apply a.loc['Total'] = pd.Series(a.sum()) I can get result as Totals for each column, but it also adds together values of Date column (dates). How can I calculate totals only for needed columns?

Body:
I have got this dataframe:

Date Trader1 Trader2 Trader3
01/04/2020  4   6   8
02/04/2020  4   6   8
03/04/2020  4   7   8
04/04/2020  4   7   8
05/04/2020  3   5   7
06/04/2020  2   4   7
07/04/2020  2   3   6
08/04/2020  3   3   6
09/04/2020  3   5   7
10/04/2020  3   5   7
11/04/2020  3   5   6

I would like to get Totals for each column by using python/pandas library. When I apply a.loc['Total'] = pd.Series(a.sum()) I can get result as Totals for each column, but it also adds together values of Date column (dates). How can I calculate totals only for needed columns?

Body:
You can select only numeric columns by DataFrame.select_dtypes:

a.loc['Total'] = a.select_dtypes(np.number).sum()

You can remove column Date by DataFrame.drop:

a.loc['Total'] = a.drop('Date', axis=1).sum()

Or select all columns without first by positions by DataFrame.iloc:

a.loc['Total'] = a.iloc[:, 1:].sum()

print (a)
             Date  Trader1  Trader2  Trader3
0      01/04/2020      4.0      6.0      8.0
1      02/04/2020      4.0      6.0      8.0
2      03/04/2020      4.0      7.0      8.0
3      04/04/2020      4.0      7.0      8.0
4      05/04/2020      3.0      5.0      7.0
5      06/04/2020      2.0      4.0      7.0
6      07/04/2020      2.0      3.0      6.0
7      08/04/2020      3.0      3.0      6.0
8      09/04/2020      3.0      5.0      7.0
9      10/04/2020      3.0      5.0      7.0
10     11/04/2020      3.0      5.0      6.0
Total         NaN     35.0     56.0     78.0


问:
How to enable Cloudwatch logging for AWS API GW via Cloudformation template
I am trying to enable cloudwatch logs for AWS API Gateway via cloudformation template but it does not enables. I have tried setting up logginglevel to INFO in both Stage description and also Method settings. Any idea on what am I missing?

When I manually enable logging through UI, it works. Not working when I try to enable through cloudformation template as below -

Note: I am just using plain cloudformation template and I have already added role ARN that has permissions to API Gateway in my account to log cloudwatch

```<code>TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO
</code>```

答:
Please add MetricsEnabled property in StageDescription to enabled CloudWatch log at stage level. If you want to enable CloudWatch logs at the method level, add MetricsEnabled property in MethodSettigns. In the following example, I have enabled logs in both places.</p>

```<code>TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MetricsEnabled: True
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO
          MetricsEnabled: True
</code>```

Body:
I am trying to enable cloudwatch logs for AWS API Gateway via cloudformation template but it does not enables. I have tried setting up logginglevel to INFO in both Stage description and also Method settings. Any idea on what am I missing?

When I manually enable logging through UI, it works. Not working when I try to enable through cloudformation template as below -

Note: I am just using plain cloudformation template and I have already added role ARN that has permissions to API Gateway in my account to log cloudwatch

TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO

Body:
Please add MetricsEnabled property in StageDescription to enabled CloudWatch log at stage level. If you want to enable CloudWatch logs at the method level, add MetricsEnabled property in MethodSettigns. In the following example, I have enabled logs in both places.

TestDeployment:
  Type: AWS::ApiGateway::Deployment
  Properties:
    Description: API Deployment
    RestApiId: testApi
    StageName: 'dev'
    StageDescription:
      Description: Stage - DEV
      LoggingLevel: INFO
      MetricsEnabled: True
      MethodSettings:
        - ResourcePath: "/testresource"
          HttpMethod: "POST"
          LoggingLevel: INFO
          MetricsEnabled: True


问:
Android Data Message (Binary SMS)
I am thinking of using SMSManager.sendDataMessage for one of my
applications.  Can anyone let me know:

Is the size limit (no. of characters) per data message, same as
text message?

If not, what is the rationale behind that and what is the limit?

Which limit does SMSManager.divideMessage uses, text message limit
or data message limit?

答:
No, they are different.

from smpp version 3.4
---- snip ----
6.2
Maximum Message Length
Each network variation is limited to some fixed maximum length. This may be
further affected by data coding scheme.
The SMSC, depending on configuration, may reject or truncate messages that
exceed the network allowed maximum.
---- snip ----

When you integrate with a telco carier, you should read into their
documentation which should mentioned what are the encoding you should use
and its corresponding length. Then cross check with your implementation.

neither. it checks the message encoding and determine the maximum length for
that message. then it will do substring to the original message and return
the splitted messages in ArrayList.

Read here on how the divideMessage called is made.
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/telephony/SmsManager.java#SmsManager.divideMessage%28java.lang.String%29
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.2_r1.1/android/telephony/SmsMessage.java#SmsMessage.fragmentText%28java.lang.String%29

ContentLicense: CC BY-SA 3.0

Title: Android Data Message (Binary SMS)


问:
How do I control the amount of times something is added to a list?
I have a list, and I am trying to add a certain amount of variables to it:

```<code>newList = ["Andrew", "Ben", "Happy"]
SecondList = [2,3,1]
BestList = []
for g in range(0,3):
    BestList.append((newList[g])*(int(SecondList[g])))
print (len(BestList))
print (BestList)
</code>```

The problem is I want the "Andrew" variable to be appended to the list 2 times, but instead, it is appended to the list only once, but as "AndrewAndrew". How do I fix my code in a way where instead of multiplying "Andrew" twice and adding it to the list as that one variable, it is added to the list twice. My end goal is for the length of BestList to be 6.

Thanks in advance.

答:
Couple of things:

If you multiply a string using * with an integer, you get a string (which is the original string repeated that many times)

If you use append only one new element is added to the list. If you want to add multiple, you need to use extend

```<code>newList = ["Andrew", "Ben", "Happy"]
SecondList = [2,3,1]
BestList = []
for g in range(0,3):
    BestList.extend([newList[g]]*SecondList[g])
print (len(BestList))
print (BestList)
</code>```

Note how I've used [newList[g]] - this turns the string from newList into a single element list. Now if you multiply this list with an int, you get another list which is the same element repeated that many times.

Result:

```<code>6
['Andrew', 'Andrew', 'Ben', 'Ben', 'Ben', 'Happy']
</code>```

If you indeed wanted something like:

```<code>[['Andrew', 'Andrew'], ['Ben', 'Ben', 'Ben'], ['Happy']]
</code>```

Simply ignore the second point and keep using append instead

Body:
I have a list, and I am trying to add a certain amount of variables to it:

newList = ["Andrew", "Ben", "Happy"]
SecondList = [2,3,1]
BestList = []
for g in range(0,3):
    BestList.append((newList[g])*(int(SecondList[g])))
print (len(BestList))
print (BestList)

The problem is I want the "Andrew" variable to be appended to the list 2 times, but instead, it is appended to the list only once, but as "AndrewAndrew". How do I fix my code in a way where instead of multiplying "Andrew" twice and adding it to the list as that one variable, it is added to the list twice. My end goal is for the length of BestList to be 6.

Thanks in advance.

Body:
Couple of things:

If you multiply a string using * with an integer, you get a string (which is the original string repeated that many times)

If you use append only one new element is added to the list. If you want to add multiple, you need to use extend

newList = ["Andrew", "Ben", "Happy"]
SecondList = [2,3,1]
BestList = []
for g in range(0,3):
    BestList.extend([newList[g]]*SecondList[g])
print (len(BestList))
print (BestList)

Note how I've used [newList[g]] - this turns the string from newList into a single element list. Now if you multiply this list with an int, you get another list which is the same element repeated that many times.

Result:

6
['Andrew', 'Andrew', 'Ben', 'Ben', 'Ben', 'Happy']

If you indeed wanted something like:

[['Andrew', 'Andrew'], ['Ben', 'Ben', 'Ben'], ['Happy']]

Simply ignore the second point and keep using append instead


问:
How can i set state value after destructing in React Hooks?
I tried to destructure and set the value in state using React Hooks,but their it shows a syntax error.Since i am new on react JS,please help me for the solution.

Following below is my code:

I set the state as following:

```<code>const [Datasets, setDatasets] = useState({
  labels: [],
  datasets: [{
      label: 'Total Cases',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(100,19,12,1)',
      borderColor: 'green',
      borderWidth: 2,
      data: []
    },
    {
      label: 'Total Recovered',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(75,192,192,1)',
      borderColor: 'rgba(0,0,0,1)',
      borderWidth: 2,
      data: []
    },
    {
      label: 'Total Deaths',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(75,192,192,1)',
      borderColor: 'rgba(0,0,0,1)',
      borderWidth: 2,
      data: []
    }
  ]
})
</code>```

I used useEffect to fetch data from API and set state.Following are my codes on useEffect:

```<code>useEffect(() => {
  axios.get('https://data.nepalcorona.info/api/v1/covid/timeline')
    .then(res => {
      setTimelinedata(res.data)
      setDatasets({ ...Datasets, labels: res.data.map((item) => item.date) })
      setDatasets([Datasets.datasets[0].data: res.data.map((item) => item.totalCases)])
        .catch(err => {
          console.log("error>>", err);
        })
    })
</code>```

when i try to run the code the  error is shown in the following code:

```<code>setDatasets([Datasets.datasets[0].data: res.data.map((item) => item.totalCases)])
</code>```

following error is shown:

following are the data i have fetched from the API:

Please help me for the solution.

答:
[Datasets.datasets[0].data: res.data.map((item) => item.totalCases)] of of setDatasets([Datasets.datasets[0].data: res.data.map((item) => item.totalCases)]) is an array, you can not have : in array like that.
Try this:

useEffect(() => {
    axios.get('https://data.nepalcorona.info/api/v1/covid/timeline')
          .then(res => {
              setTimelinedata(res.data)
              const labels = res.data.map((item) => item.date)
              const data = res.data.map((item) => item.totalCases)
              setDatasets({ labels: res.data.map((item) => item.date, [{...Datasets.datasets[0], data: data}, ...Datasets.datasets])})
          .catch(err => {
              console.log("error>>", err);
          })
    })```

Body:
I tried to destructure and set the value in state using React Hooks,but their it shows a syntax error.Since i am new on react JS,please help me for the solution.

Following below is my code:

I set the state as following:

const [Datasets, setDatasets] = useState({
  labels: [],
  datasets: [{
      label: 'Total Cases',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(100,19,12,1)',
      borderColor: 'green',
      borderWidth: 2,
      data: []
    },
    {
      label: 'Total Recovered',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(75,192,192,1)',
      borderColor: 'rgba(0,0,0,1)',
      borderWidth: 2,
      data: []
    },
    {
      label: 'Total Deaths',
      fill: false,
      lineTension: 0.5,
      backgroundColor: 'rgba(75,192,192,1)',
      borderColor: 'rgba(0,0,0,1)',
      borderWidth: 2,
      data: []
    }
  ]
})

I used useEffect to fetch data from API and set state.Following are my codes on useEffect:

useEffect(() => {
  axios.get('https://data.nepalcorona.info/api/v1/covid/timeline')
    .then(res => {
      setTimelinedata(res.data)
      setDatasets({ ...Datasets, labels: res.data.map((item) => item.date) })
      setDatasets([Datasets.datasets[0].data: res.data.map((item) => item.totalCases)])
        .catch(err => {
          console.log("error>>", err);
        })
    })

when i try to run the code the  error is shown in the following code:

setDatasets([Datasets.datasets[0].data: res.data.map((item) => item.totalCases)])

following error is shown:

following are the data i have fetched from the API:

Please help me for the solution.


问:
Cannot detect key event for Android Barcode Scanner input, JavaScript

Scope

I am attempting to detect character input from a barcode scanner integrated into a hand-held Android device in a simple web application using JavaScript. Since most barcode scanners behave like a keyboard wedge I am using detecting events keypress and/or keyup to interpret and handle the character input.

I don't want the character input to populate a text input, so I have assigned the event handler to document, however, I know I could also assign it to the window.

Sample Code

My sample code for completing the task looks like this; This sample doesn't differentiate between keyboard input and scanner input, but I have already solved that problem.

```<code>var barcodeString = "";

$(document).keypress(function (event) {
    // If character is carriage-return prevent submit.
    if (event.which === 13) {
        event.preventDefault();
    }
    // Append other characters to barcodeString.
    barcodeString += event.key;
});
</code>```

Problem

My problem is that many devices do not return any readable characters at all. When I monitor the character codes using event.keyCode I receive two codes: 229 and 13. This article W3 keyCode in key events and this StackOverflow answer Is it OK to ignore keydown events with keyCode = 229? outlines that the 229 code means the Input Monitor is busy. I can only assume this is either because:

The barcode scanner locks the Input Monitor upon inserting the characters.

The speed of the character input causes the Input Monitor to become too busy to detect character input.

Interestingly enough, if I detect event.keyCode while scanning the text into a text input, the two character codes: 229 and 13 are detected and only afterward the text is then inserted into the text input.

Devices

The devices I am attempting to implement this on are Nautiz X2 made by the Handheld Group. And another Android device, which I am unable to identify the brand of but seems slightly more generic with different barcode scanning software.

Workarounds

1

The Handheld Group do provide a JavaScript API for interacting with the Handheld Scanner. The way this works is they provide an APK for a custom browser named: Kiosk Browser and implement the interpretation of the JavaScript specific to the scanner there. Documentation can be found here (it's exceedingly short and not a long read): JavaScript Scanner Interface

2

The more generic Android device has the ability to 'slow-down' character input on the scanner to make the scanner more compatible with third-party applications. Behold, toggling this option allows me to detect character input. Although event.key always returns code 229 (this time from an unreadable character), but String.fromCharCode(event.which) will somewhat solve the problem (it doesn't deal with special characters). The Nautiz X2 does not have the option to 'slow-down' input in the software settings.

3

The alternative workaround I have considered is putting a text input onto the web page with the style display: none to hide it and use JavaScript to continually set focus on the input. The I can attempt to monitor onChange and handle the character input. I would really like to avoid this approach.

Summary

The workarounds I have presented seem awful and the first is not device independent. I was wondering if there is a better place to "dump" text input from the barcode scanner so I can handle it in my application? Or, is there an event I can monitor to detect the character input?

答:
I know this is late, but I am facing a similar problem with a range of devices including the Zebra TC20 and Chainway C71. After a lot of searching around I found this amazing Codepen sample by Bob Jase. He has documented his solution in the code, but I'll repost it here for archive purposes. link to his CodePen

His solution uses a hidden  element to change the focus to from a visible  element and thus hiding the soft android keyboard.

// whenever the visible field gets focused
$("#visibleField").bind("focus", function(e) {
  // silently shift the focus to the hidden select box
  $("#hiddenField").focus();
  $("#cursorMeasuringDiv").css("font", $("#visibleField").css("font"));
});

// whenever the user types on his keyboard in the select box
// which is natively supported for jumping to an <option>
$("#hiddenField").bind("keypress",function(e) {
  // get the current value of the readonly field
  var currentValue = $("#visibleField").val();

  // and append the key the user pressed into that field
  $("#visibleField").val(currentValue + e.key);
  $("#cursorMeasuringDiv").text(currentValue + e.key);

  // measure the width of the cursor offset
  var offset = 3;
  var textWidth = $("#cursorMeasuringDiv").width();
  $("#hiddenField").css("marginLeft",Math.min(offset+textWidth,$("#visibleField").width()));

});```
<pre class="snippet-code-css lang-css prettyprint-override"><code>#hiddenField {
  height:17px;
  width:1px;
  position:absolute;
  margin-left:3px;
  margin-top:2px;
  border:none;
  border-width:0px 0px 0px 1px;
}

#cursorMeasuringDiv {
  position:absolute;
  visibility:hidden;
  margin:0px;
  padding:0px;
}

#hiddenField:focus {
  border:1px solid gray;
  border-width:0px 0px 0px 1px;
  outline:none;
  animation-name: cursor;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}

@keyframes cursor {
    from {opacity:0;}
    to {opacity:1;}
}</code>```

Click on the field and type (it should work even though the field isn't really focused):

input: <select id="hiddenField" />

<input type="text" readonly="readonly" id="visibleField" />

```

I hope this helps. Again, kudos to Bob for working this out!

Body:
Scope

I am attempting to detect character input from a barcode scanner integrated into a hand-held Android device in a simple web application using JavaScript. Since most barcode scanners behave like a keyboard wedge I am using detecting events keypress and/or keyup to interpret and handle the character input.

I don't want the character input to populate a text input, so I have assigned the event handler to document, however, I know I could also assign it to the window.

Sample Code

My sample code for completing the task looks like this; This sample doesn't differentiate between keyboard input and scanner input, but I have already solved that problem.

var barcodeString = "";

$(document).keypress(function (event) {
    // If character is carriage-return prevent submit.
    if (event.which === 13) {
        event.preventDefault();
    }
    // Append other characters to barcodeString.
    barcodeString += event.key;
});

Problem

My problem is that many devices do not return any readable characters at all. When I monitor the character codes using event.keyCode I receive two codes: 229 and 13. This article W3 keyCode in key events and this StackOverflow answer Is it OK to ignore keydown events with keyCode = 229? outlines that the 229 code means the Input Monitor is busy. I can only assume this is either because:

The barcode scanner locks the Input Monitor upon inserting the characters.

The speed of the character input causes the Input Monitor to become too busy to detect character input.

Interestingly enough, if I detect event.keyCode while scanning the text into a text input, the two character codes: 229 and 13 are detected and only afterward the text is then inserted into the text input.

Devices

The devices I am attempting to implement this on are Nautiz X2 made by the Handheld Group. And another Android device, which I am unable to identify the brand of but seems slightly more generic with different barcode scanning software.

Workarounds

1

The Handheld Group do provide a JavaScript API for interacting with the Handheld Scanner. The way this works is they provide an APK for a custom browser named: Kiosk Browser and implement the interpretation of the JavaScript specific to the scanner there. Documentation can be found here (it's exceedingly short and not a long read): JavaScript Scanner Interface

2

The more generic Android device has the ability to 'slow-down' character input on the scanner to make the scanner more compatible with third-party applications. Behold, toggling this option allows me to detect character input. Although event.key always returns code 229 (this time from an unreadable character), but String.fromCharCode(event.which) will somewhat solve the problem (it doesn't deal with special characters). The Nautiz X2 does not have the option to 'slow-down' input in the software settings.

3

The alternative workaround I have considered is putting a text input onto the web page with the style display: none to hide it and use JavaScript to continually set focus on the input. The I can attempt to monitor onChange and handle the character input. I would really like to avoid this approach.

Summary

The workarounds I have presented seem awful and the first is not device independent. I was wondering if there is a better place to "dump" text input from the barcode scanner so I can handle it in my application? Or, is there an event I can monitor to detect the character input?

Body:
I know this is late, but I am facing a similar problem with a range of devices including the Zebra TC20 and Chainway C71. After a lot of searching around I found this amazing Codepen sample by Bob Jase. He has documented his solution in the code, but I'll repost it here for archive purposes. link to his CodePen

His solution uses a hidden  element to change the focus to from a visible  element and thus hiding the soft android keyboard.

// whenever the visible field gets focused
$("#visibleField").bind("focus", function(e) {
  // silently shift the focus to the hidden select box
  $("#hiddenField").focus();
  $("#cursorMeasuringDiv").css("font", $("#visibleField").css("font"));
});

// whenever the user types on his keyboard in the select box
// which is natively supported for jumping to an <option>
$("#hiddenField").bind("keypress",function(e) {
  // get the current value of the readonly field
  var currentValue = $("#visibleField").val();

  // and append the key the user pressed into that field
  $("#visibleField").val(currentValue + e.key);
  $("#cursorMeasuringDiv").text(currentValue + e.key);

  // measure the width of the cursor offset
  var offset = 3;
  var textWidth = $("#cursorMeasuringDiv").width();
  $("#hiddenField").css("marginLeft",Math.min(offset+textWidth,$("#visibleField").width()));

});

#hiddenField {
  height:17px;
  width:1px;
  position:absolute;
  margin-left:3px;
  margin-top:2px;
  border:none;
  border-width:0px 0px 0px 1px;
}

#cursorMeasuringDiv {
  position:absolute;
  visibility:hidden;
  margin:0px;
  padding:0px;
}

#hiddenField:focus {
  border:1px solid gray;
  border-width:0px 0px 0px 1px;
  outline:none;
  animation-name: cursor;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}

@keyframes cursor {
    from {opacity:0;}
    to {opacity:1;}
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the field and type (it should work even though the field isn't really focused):
<p />

<!-- must be a select box with no children to suppress the keyboard -->
input: <select id="hiddenField" />
<span id="fakecursor" />

<input type="text" readonly="readonly" id="visibleField" />
<div id="cursorMeasuringDiv" />

I hope this helps. Again, kudos to Bob for working this out!


问:
How to use default browser profile in Selenium instead of new one?
I couldn't find any relevant answers and my question is pretty straight forward.

The context isn't really relevant.

It is very important for me that Selenium uses my normally installed browser (Chrome or Firefox), when doing coded things.

答:
Maybe using your standard profile helps? It did in my case where the website was detecting the Selenium browser. This code solved my problem.  </p>

```<code>path = str(Path.home())
path = path + "/.mozilla/firefox/xxxx.default-release"
profile = FirefoxProfile(path)
driver = webdriver.Firefox(profile)
</code>```

Body:
Maybe using your standard profile helps? It did in my case where the website was detecting the Selenium browser. This code solved my problem.

path = str(Path.home())
path = path + "/.mozilla/firefox/xxxx.default-release"
profile = FirefoxProfile(path)
driver = webdriver.Firefox(profile)


问:
jquery autoload not working with multiple field having same class
html code

```<code>                   <div class="multi-field-wrapper panel-body">
                                <div class="multi-fields " >
                                    <div class="multi-field row form-group">
                                        <div class="col-lg-2">
                                            <input type="text" name="box_no[]"  placeholder="Box No" class="form-control" required>

                                        </div>
                                        <div class="col-lg-4">
                                            <input type="text" name="product_name[]"  placeholder="Product Name" class="auto form-control" required>
                                        </div>

                                        <div class="mb-md hidden-lg hidden-xl"></div>

                                        <div class="col-lg-2">
                                            <input type="text" name="product_quantity[]" id="product_quantity" placeholder="Quantity" class="form-control" required>
                                        </div>

                                        <div class="mb-md hidden-lg hidden-xl"></div>

                                        <div class="col-lg-2">
                                            <input type="text" name="price[]"  placeholder="Price" class="form-control" required>
                                        </div>
                                        <div class="mb-md hidden-lg hidden-xl"></div>
                                        <div class="col-lg-2">
                                            <button class="remove-field btn-success" type="button"><i class="fa fa-minus"></i></button>
                                        </div>
                                    </div>
                                </div>
                                <br>
                                 <button type="button" class="add-field btn-primary">Add More Product</button>
                                </div>
</code>```

javascript for autoload

```<code>    $(function(){
        $(".auto").each(function(){
            $(this).autocomplete({
                source: "<?=BASE_ADMIN_URL?>invoice/getAutoCompliteData" ,
            });
        });
    });
</code>```

i am adding row dynamically with this code

```<code>$(document).ready(function() {
    $('.multi-field-wrapper').each(function() {
        var $wrapper = $('.multi-fields', this);

        $(".add-field", $(this)).click(function(e) {
            $('.multi-field:first-child', $wrapper).clone(true).appendTo($wrapper).find('input:text').val('').focus();
        });

        $('.multi-field .remove-field', $wrapper).click(function() {
            if ($('.multi-field', $wrapper).length > 1)
                $(this).parent().parent('.multi-field').remove();
        });
    });

});
</code>```

Problem is autoload works fine with first element of class

But when i add another element autoload shows result only on first element

答:
Here,  "multi-field-wrapper" is a parent class that is not repeating and "auto" is a class of the fields under repeating area where you want to initialize the autocomplete. Its working perfect for me.</p>

```<code>$(".multi-field-wrapper").on('focus',".auto",function(){
    $(this).autocomplete({
            source: "<?=BASE_ADMIN_URL?>invoice/getAutoCompliteData" ,
    });
});
</code>```

Body:
html code

                                            <input type="text" name="box_no[]"  placeholder="Box No" class="form-control" required>

                                            <input type="text" name="product_name[]"  placeholder="Product Name" class="auto form-control" required>

                                            <input type="text" name="product_quantity[]" id="product_quantity" placeholder="Quantity" class="form-control" required>

                                            <input type="text" name="price[]"  placeholder="Price" class="form-control" required>

                                            <button class="remove-field btn-success" type="button"></button>

                                 <button type="button" class="add-field btn-primary">Add More Product</button>

javascript for autoload

    $(function(){
        $(".auto").each(function(){
            $(this).autocomplete({
                source: "<?=BASE_ADMIN_URL?>invoice/getAutoCompliteData" ,
            });
        });
    });

i am adding row dynamically with this code

$(document).ready(function() {
    $('.multi-field-wrapper').each(function() {
        var $wrapper = $('.multi-fields', this);

        $(".add-field", $(this)).click(function(e) {
            $('.multi-field:first-child', $wrapper).clone(true).appendTo($wrapper).find('input:text').val('').focus();
        });

        $('.multi-field .remove-field', $wrapper).click(function() {
            if ($('.multi-field', $wrapper).length > 1)
                $(this).parent().parent('.multi-field').remove();
        });
    });

});

Problem is autoload works fine with first element of class

But when i add another element autoload shows result only on first element

Body:
Here,  "multi-field-wrapper" is a parent class that is not repeating and "auto" is a class of the fields under repeating area where you want to initialize the autocomplete. Its working perfect for me.

$(".multi-field-wrapper").on('focus',".auto",function(){
    $(this).autocomplete({
            source: "<?=BASE_ADMIN_URL?>invoice/getAutoCompliteData" ,
    });
});


问:
How to manage repeater with non fixed column number
I am using repeater to bind all table data.

And My table fields are Name,Option1,Option2... Option12. All total 13 columns.
values for Option columns are dynamic. some time it contains two values for Option1 and 2 and some times figure can be change between 1 to 12.

Now i want to show only those option columns that contain some value.

Like this:-

```<code>Name
Option1
Option2
Option8

Name
Option10
Option12
Option4
Otion3

Name
Option5
Option7

Name
Option3
Option2
Option5
Option12
Option4
</code>```

Means options are not fixed. how can i manage this with Repeater control.
SO it can show value like this. Please suggest me the correct way to solve this.

Thanks in Advance.

First Edit

```<code><%# !Equals(DataBinder.Eval(Container.DataItem, "Option1")%>
....
<%# !Equals(DataBinder.Eval(Container.DataItem, "Option12")%>
</code>```

Suppose i have this 12 Options like this.
Now if my data source contains values only Option 1 to 5 then i need that rest of 6 to 12 options will not show on repeater.

答:
Try this it's helpful for you,

                    ID

                    Name

                    Orders

```<code>  <ItemTemplate>
        <tr style="background-color:FFECD8">
           <td valign="top">
              <%# DataBinder.Eval(Container.DataItem, "ID") %>
           </td>
           <td valign="top">
              <%# DataBinder.Eval(Container.DataItem,"Name") %>
           </td>
           <td>
             <asp:Repeater Runat="server" ID="ordersRepeater" EnableViewState="false"
                DataSource='<%# DataBinder.Eval(Container.DataItem, "Orders") %>'>
                <ItemTemplate>
                    <%# DataBinder.Eval(Container.DataItem, "OrderID") %> - <%# DataBinder.Eval(Container.DataItem, "OrderName") %> - <%# DataBinder.Eval(Container.DataItem, "OrderCost")%>
                    <br />
                </ItemTemplate>
            </asp:Repeater>
           </td>
        </tr>
  </ItemTemplate>

  <FooterTemplate>
     </Table>
  </FooterTemplate>
</code>```

The code behind is as follows:

using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Data.SqlClient;
  using System.Configuration;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;

using System.Text;
using System.Xml;
using System.Xml.Schema;

public class Customer
{
    private int id;
    public int ID
    {
        get { return this.id; }
        set { this.id = value; }
    }

```<code>private string name;
public string Name
{
    get { return this.name; }
    set { this.name = value; }
}

public List orders;
public List Orders
{
    get { return this.orders; }
    set { this.orders = value; }
}
</code>```

}

public class Order
{
    private int orderID;
    public int OrderID
    {
        get { return this.orderID; }
        set { this.orderID = value; }
    }
    private string orderName;
    public string OrderName
    {
        get { return this.orderName; }
        set { this.orderName = value; }
    }
    private decimal orderCost;
    public decimal OrderCost
    {
        get { return this.orderCost; }
        set { this.orderCost = value; }
    }
}

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        List orders1 = new List();
        Order order1 = new Order();
        order1.OrderID = 1;
        order1.OrderName = "Pepsi";
        order1.OrderCost = 12.5M;
        orders1.Add(order1);

```<code>    Order order2 = new Order();
    order2.OrderID = 2;
    order2.OrderName = "7up";
    order2.OrderCost = 12M;
    orders1.Add(order2);

    List orders2 = new List();
    Order order3 = new Order();
    order3.OrderID = 4;
    order3.OrderName = "Food";
    order3.OrderCost = 12.5M;
    orders2.Add(order3);

    List customers = new List();
    Customer c1 = new Customer();
    c1.ID = 1;
    c1.Name = "Bilal";
    c1.Orders = orders1;
    customers.Add(c1);

    Customer c2 = new Customer();
    c2.ID = 2;
    c2.Name = "potterosa";
    c2.Orders = orders2;
    customers.Add(c2);

    this.Repeater1.DataSource = customers;
    this.Repeater1.DataBind();
}

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

}
</code>```

}

Go through following link

http://forums.asp.net/t/1118175.aspx/1

Body:
I am using repeater to bind all table data.

And My table fields are Name,Option1,Option2... Option12. All total 13 columns.
values for Option columns are dynamic. some time it contains two values for Option1 and 2 and some times figure can be change between 1 to 12.

Now i want to show only those option columns that contain some value.

Like this:-

Name
Option1
Option2
Option8

Name
Option10
Option12
Option4
Otion3

Name
Option5
Option7

Name
Option3
Option2
Option5
Option12
Option4

Means options are not fixed. how can i manage this with Repeater control.
SO it can show value like this. Please suggest me the correct way to solve this.

Thanks in Advance.

First Edit

<%# !Equals(DataBinder.Eval(Container.DataItem, "Option1")%>
....
<%# !Equals(DataBinder.Eval(Container.DataItem, "Option12")%>

Suppose i have this 12 Options like this.
Now if my data source contains values only Option 1 to 5 then i need that rest of 6 to 12 options will not show on repeater.

Body:
Try this it's helpful for you,

                    ID

                    Name

                    Orders

  <ItemTemplate>
        <tr style="background-color:FFECD8">
           <td valign="top">
              <%# DataBinder.Eval(Container.DataItem, "ID") %>
           </td>
           <td valign="top">
              <%# DataBinder.Eval(Container.DataItem,"Name") %>
           </td>
           <td>
             <asp:Repeater Runat="server" ID="ordersRepeater" EnableViewState="false"
                DataSource='<%# DataBinder.Eval(Container.DataItem, "Orders") %>'>
                <ItemTemplate>
                    <%# DataBinder.Eval(Container.DataItem, "OrderID") %> - <%# DataBinder.Eval(Container.DataItem, "OrderName") %> - <%# DataBinder.Eval(Container.DataItem, "OrderCost")%>
                    <br />
                </ItemTemplate>
            </asp:Repeater>
           </td>
        </tr>
  </ItemTemplate>

  <FooterTemplate>
     </Table>
  </FooterTemplate>

The code behind is as follows:

using System;
  using System.Collections.Generic;
  using System.Data;
  using System.Data.SqlClient;
  using System.Configuration;
  using System.Web;
  using System.Web.Security;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.WebControls.WebParts;
  using System.Web.UI.HtmlControls;

using System.Text;
using System.Xml;
using System.Xml.Schema;

public class Customer
{
    private int id;
    public int ID
    {
        get { return this.id; }
        set { this.id = value; }
    }

private string name;
public string Name
{
    get { return this.name; }
    set { this.name = value; }
}

public List orders;
public List Orders
{
    get { return this.orders; }
    set { this.orders = value; }
}

}

public class Order
{
    private int orderID;
    public int OrderID
    {
        get { return this.orderID; }
        set { this.orderID = value; }
    }
    private string orderName;
    public string OrderName
    {
        get { return this.orderName; }
        set { this.orderName = value; }
    }
    private decimal orderCost;
    public decimal OrderCost
    {
        get { return this.orderCost; }
        set { this.orderCost = value; }
    }
}

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        List orders1 = new List();
        Order order1 = new Order();
        order1.OrderID = 1;
        order1.OrderName = "Pepsi";
        order1.OrderCost = 12.5M;
        orders1.Add(order1);

    Order order2 = new Order();
    order2.OrderID = 2;
    order2.OrderName = "7up";
    order2.OrderCost = 12M;
    orders1.Add(order2);

    List orders2 = new List();
    Order order3 = new Order();
    order3.OrderID = 4;
    order3.OrderName = "Food";
    order3.OrderCost = 12.5M;
    orders2.Add(order3);

    List customers = new List();
    Customer c1 = new Customer();
    c1.ID = 1;
    c1.Name = "Bilal";
    c1.Orders = orders1;
    customers.Add(c1);

    Customer c2 = new Customer();
    c2.ID = 2;
    c2.Name = "potterosa";
    c2.Orders = orders2;
    customers.Add(c2);

    this.Repeater1.DataSource = customers;
    this.Repeater1.DataBind();
}

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{

}

}

Go through following link

http://forums.asp.net/t/1118175.aspx/1


问:
Flutter - Open Specific Page from FCM Background Notification
I am working with Firebase Cloud Messaging to send notifications to my Flutter app. As of right now, when I click on a background notification it proceeds to open the app.

That's nice but I would like it to be that after clicking the background push notification, it opens a specific page in my app. How does one do this? I have researched this thoroughly and can't seem to find anything that makes sense. Code examples or detailed links preferred please.

答: I resolved this by adding "click_action": 'FLUTTER_NOTIFICATION_CLICK' to my data payload!


问:
How to select specific range of data column with C#
I am trying to display several data, but I cannot select the column that I want. My code will produce all of the column data values. I have 9 columns in data table (zero-based), and I just want to get the data from column 3 till column 9. Grateful for any kind of insight!</p>

```<code>foreach (DataColumn column in dt.Columns)
    {
        int i = dt.Columns.IndexOf(column);
        int colCount = dt.Columns.Count;

        for (i = 3; i < colCount; i++)
            {
                html.Append("<div class='col col-" + column.Ordinal + "' data-label='" + column.ColumnName + "'>");
                html.Append(row[column.ColumnName]);
                html.Append("</div>");
            }
    }
</code>```

答:
The problem seems to be that you have two loops.
Wouldn't the below code achieve what you want?</p>

```<code>int colCount = dt.Columns.Count
for (i = 3; i < colCount; i++)
        {
            DataColumn column = dt.Columns[i];

            html.Append("<div class='col col-" + column.Ordinal + "' data-label='" + column.ColumnName + "'>");
            html.Append(row[column.ColumnName]);
            html.Append("</div>");
        }
</code>```

Body:
I am trying to display several data, but I cannot select the column that I want. My code will produce all of the column data values. I have 9 columns in data table (zero-based), and I just want to get the data from column 3 till column 9. Grateful for any kind of insight!

foreach (DataColumn column in dt.Columns)
    {
        int i = dt.Columns.IndexOf(column);
        int colCount = dt.Columns.Count;

        for (i = 3; i < colCount; i++)
            {
                html.Append("
");
                html.Append(row[column.ColumnName]);
                html.Append("
");
            }
    }

Body:
The problem seems to be that you have two loops.
Wouldn't the below code achieve what you want?

int colCount = dt.Columns.Count
for (i = 3; i < colCount; i++)
        {
            DataColumn column = dt.Columns[i];

            html.Append("<div class='col col-" + column.Ordinal + "' data-label='" + column.ColumnName + "'>");
            html.Append(row[column.ColumnName]);
            html.Append("</div>");
        }


问:
Rails server reduce verbosity?
One method of debugging within the Controllers I have learnt from Django is to actually print out variables within the controllers itself. However, I realize that this method is not as practical in rails as the default rails webserver is pretty verbose and it's making me difficult to trace.

FYI I read about the rails debugging page but most of those debug techniques exist in the VIEW layer (like <% @myvar.debug %>). I want to be able to see the state of vars inside the controllers and I don't want to use the rails debugger as it's kind of an overkill for something so simple.

My question is: is there a variable that I can set to reduce statements like those below from being produced at each page serve?

```<code>Started POST "/submissions" for 127.0.0.1 at 2011-06-02 02:35:38 -0400
  Processing by SubmissionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"U+I2mSfCRFvOyT/L82TTzsVRVJQuJbB+X3SaMWr/IM4=", "submission"=>{"url"=>"http://wasdvasd.com", "receiver_id"=>"1", "comment"=>"asdvasdvasdv"}, "commit"=>"Create Submission"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Link Load (0.1ms)  SELECT "links".* FROM "links" WHERE "links"."url" = 'http://wasdvasd.com' LIMIT 1
  AREL (0.3ms)  INSERT INTO "links" ("url", "created_at", "updated_at") VALUES ('http://wasdvasd.com', '2011-06-02 06:35:38.399463', '2011-06-02 06:35:38.399463')
  AREL (0.2ms)  INSERT INTO "submissions" ("link_id", "author_id", "receiver_id", "comment", "visited", "created_at", "updated_at") VALUES (5, 1, 1, 'asdvasdvasdv', NULL, '2011-06-02 06:35:38.402094', '2011-06-02 06:35:38.402094')
Redirected to http://localhost:3000/submissions
Completed 302 Found in 244ms
</code>```

答:
You should be able to change the logging level in your config/environments/*.rb files.

See: http://guides.rubyonrails.org/debugging_rails_applications.html#log-levels for the different log levels.

Title: Rails server reduce verbosity?

Body:
One method of debugging within the Controllers I have learnt from Django is to actually print out variables within the controllers itself. However, I realize that this method is not as practical in rails as the default rails webserver is pretty verbose and it's making me difficult to trace.

FYI I read about the rails debugging page but most of those debug techniques exist in the VIEW layer (like <% @myvar.debug %>). I want to be able to see the state of vars inside the controllers and I don't want to use the rails debugger as it's kind of an overkill for something so simple.

My question is: is there a variable that I can set to reduce statements like those below from being produced at each page serve?

Started POST "/submissions" for 127.0.0.1 at 2011-06-02 02:35:38 -0400
  Processing by SubmissionsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"U+I2mSfCRFvOyT/L82TTzsVRVJQuJbB+X3SaMWr/IM4=", "submission"=>{"url"=>"http://wasdvasd.com", "receiver_id"=>"1", "comment"=>"asdvasdvasdv"}, "commit"=>"Create Submission"}
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 1 LIMIT 1
  Link Load (0.1ms)  SELECT "links".* FROM "links" WHERE "links"."url" = 'http://wasdvasd.com' LIMIT 1
  AREL (0.3ms)  INSERT INTO "links" ("url", "created_at", "updated_at") VALUES ('http://wasdvasd.com', '2011-06-02 06:35:38.399463', '2011-06-02 06:35:38.399463')
  AREL (0.2ms)  INSERT INTO "submissions" ("link_id", "author_id", "receiver_id", "comment", "visited", "created_at", "updated_at") VALUES (5, 1, 1, 'asdvasdvasdv', NULL, '2011-06-02 06:35:38.402094', '2011-06-02 06:35:38.402094')
Redirected to http://localhost:3000/submissions
Completed 302 Found in 244ms


问:
Execution failed due to configuration error: Invalid permissions on Lambda function
I am building a serverless application using AWS Lambda and API Gateway via Visual Studio. I am working in C#, and using the serverless application model (SAM) in order to deploy my API. I build the code in Visual Studio, then deploy via publish to Lambda. This is working, except every time I do a new build, and try to execute an API call, I get this error:

Execution failed due to configuration error: Invalid permissions on Lambda function

Doing some research, I found this fix mentioned elsewhere (to be done via the AWS Console):

Fix: went to API Gateway > API name > Resources > Resource name > Method > Integration Request > Lambda Function and reselected my existing function, before "saving" it with the little checkmark.

Now this works for me, but it breaks the automation of using the serverless.template (JSON) to build out my API. Does anyone know how to fix this within the serverless.template file? So that I don't need to take action in the console to resolve? Here's a sample of one of my methods from the serverless.template file

```<code>{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Transform" : "AWS::Serverless-2016-10-31",
  "Description" : "An AWS Serverless Application.",

  "Resources" : {

    "Get" : {
      "Type" : "AWS::Serverless::Function",
      "Properties": {
        "VpcConfig":{
          "SecurityGroupIds" : ["sg-111a1476"],
          "SubnetIds" : [ "subnet-3029a769","subnet-5ec0b928"]
        },
        "Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::Get",
        "Runtime": "dotnetcore2.0",
        "CodeUri": "",
        "MemorySize": 256,
        "Timeout": 30,
        "Role": null,
        "Policies": [ "AWSLambdaBasicExecutionRole","AWSLambdaVPCAccessExecutionRole","AmazonSSMFullAccess"],
        "Events": {
          "PutResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/",
              "Method": "GET"
            }
          }
        }
      }
    },
</code>```

答:
I had the same issue. I changed the integration to mock first, i.e unsetting the integration type to Lambda, and then after one deployment, set the integration type to lambda again. It worked flawlessly thereafter.

I hope it helps.

Body:
I am building a serverless application using AWS Lambda and API Gateway via Visual Studio. I am working in C#, and using the serverless application model (SAM) in order to deploy my API. I build the code in Visual Studio, then deploy via publish to Lambda. This is working, except every time I do a new build, and try to execute an API call, I get this error:

Execution failed due to configuration error: Invalid permissions on Lambda function

Doing some research, I found this fix mentioned elsewhere (to be done via the AWS Console):

Fix: went to API Gateway > API name > Resources > Resource name > Method > Integration Request > Lambda Function and reselected my existing function, before "saving" it with the little checkmark.

Now this works for me, but it breaks the automation of using the serverless.template (JSON) to build out my API. Does anyone know how to fix this within the serverless.template file? So that I don't need to take action in the console to resolve? Here's a sample of one of my methods from the serverless.template file

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Transform" : "AWS::Serverless-2016-10-31",
  "Description" : "An AWS Serverless Application.",

  "Resources" : {

    "Get" : {
      "Type" : "AWS::Serverless::Function",
      "Properties": {
        "VpcConfig":{
          "SecurityGroupIds" : ["sg-111a1476"],
          "SubnetIds" : [ "subnet-3029a769","subnet-5ec0b928"]
        },
        "Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::Get",
        "Runtime": "dotnetcore2.0",
        "CodeUri": "",
        "MemorySize": 256,
        "Timeout": 30,
        "Role": null,
        "Policies": [ "AWSLambdaBasicExecutionRole","AWSLambdaVPCAccessExecutionRole","AmazonSSMFullAccess"],
        "Events": {
          "PutResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/",
              "Method": "GET"
            }
          }
        }
      }
    },


问:
pm2 process not starting again after using ```pm2 stop index.js```
Ive been trying to fix this problem and havent found much of anything to help me with this. I used pm2 stop index.js from my cmd and now its staying as disabled. I tried disabling watch mode but that didnt do anything. This might be something really stupid but i dont know.

答:
Try stopping with the id

```<code>pm2 stop 0
</code>```

Then start with the command

```<code>pm2 start --name <NAME> <PATH>
</code>```

Body:
Try stopping with the id

pm2 stop 0

Then start with the command

pm2 start --name <NAME> <PATH>


问:
How can I upload image with form data?
I am learning React Native with Expo. For a test project, I have a screen named "Create profile" where I am trying to add the image selected on the Expo image picker with other text inputs - location, description. How do I combined the inputs along with the image from the image picker?

My current guess is to use base64 for the image or set the image input as "this.state.image" to call the image:uri from the picker. Though I may be going the wrong way with this. Also another option is to use Content-Type:multipart-form/data though when tried it doesn't post any data to the API call.

The API is built on a Django app using Django Rest Framework.

My Code is below:
        render() {
    let { image } = this.state;

```<code>function handleSubmit(props) {
  fetch('<API URL HERE>', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body:JSON.stringify({
      'location': this.state.location,
      'description': this.state.description,
      //user image field and input below
      'user_image':this.state.image

    })
  });
}
</code>```

Image picker

```<code>_pickImage = async () => {
try {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
  });
  if (!result.cancelled) {
    const image = result.uri;
    this.setState({ image: result.uri });
  }

  console.log(result);
} catch (E) {
  console.log(E);
}
</code>```

};

答:
I just managed to figure this out and for the benefit of others who want a similar result, I've posted it here.

For the image picker you need to add other variables such as the image uri, filename, and file type.

```<code>  _pickImage = async () => {
   try {
   let result = await ImagePicker.launchImageLibraryAsync({
     mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
   });
     if (!result.cancelled) {
this.setState({ image: result.uri });

let localUri = result.uri;
let filename = localUri.split('/').pop();

// Infer the type of the image
let match = /\.(\w+)$/.exec(filename);
let type = match ? `image/${match[1]}` : `image`;

this.setState({ localUri: result.uri });
this.setState({ filename: filename });
this.setState({ type: type });

  }
</code>```

Then for the form data, you'll have to adjust the image field to include those variables when submitting them along with the other fields.

```<code>    let formData = new FormData();
    formData.append('location',this.state.location);
    formData.append('description',this.state.description);
    formData.append('member_unique','IEQ');
    formData.append('user_image', {type:type, uri:uri, name:filename});

 function handleSubmit(props) {
  fetch('<posting api>', {
    method: 'POST',
    body:formData,

  });
}
</code>```

Title: How can I upload image with form data?

Body:
I am learning React Native with Expo. For a test project, I have a screen named "Create profile" where I am trying to add the image selected on the Expo image picker with other text inputs - location, description. How do I combined the inputs along with the image from the image picker?

My current guess is to use base64 for the image or set the image input as "this.state.image" to call the image:uri from the picker. Though I may be going the wrong way with this. Also another option is to use Content-Type:multipart-form/data though when tried it doesn't post any data to the API call.

The API is built on a Django app using Django Rest Framework.

My Code is below:
        render() {
    let { image } = this.state;

function handleSubmit(props) {
  fetch('<API URL HERE>', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Content-Type': 'application/json',
    },
    body:JSON.stringify({
      'location': this.state.location,
      'description': this.state.description,
      //user image field and input below
      'user_image':this.state.image

    })
  });
}

Image picker

_pickImage = async () => {
try {
  let result = await ImagePicker.launchImageLibraryAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.All,
    allowsEditing: true,
    aspect: [4, 3],
    quality: 1,
  });
  if (!result.cancelled) {
    const image = result.uri;
    this.setState({ image: result.uri });
  }

  console.log(result);
} catch (E) {
  console.log(E);
}

};

Body:
I just managed to figure this out and for the benefit of others who want a similar result, I've posted it here.

For the image picker you need to add other variables such as the image uri, filename, and file type.

  _pickImage = async () => {
   try {
   let result = await ImagePicker.launchImageLibraryAsync({
     mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
   });
     if (!result.cancelled) {
this.setState({ image: result.uri });

let localUri = result.uri;
let filename = localUri.split('/').pop();

// Infer the type of the image
let match = /\.(\w+)$/.exec(filename);
let type = match ? `image/${match[1]}` : `image`;

this.setState({ localUri: result.uri });
this.setState({ filename: filename });
this.setState({ type: type });

  }

Then for the form data, you'll have to adjust the image field to include those variables when submitting them along with the other fields.

    let formData = new FormData();
    formData.append('location',this.state.location);
    formData.append('description',this.state.description);
    formData.append('member_unique','IEQ');
    formData.append('user_image', {type:type, uri:uri, name:filename});

 function handleSubmit(props) {
  fetch('<posting api>', {
    method: 'POST',
    body:formData,

  });
}


问:
Rails 5.2 Shrine and Tus server: Cannot create a custom folder structure to save files
I am using rails 5.2, Shrine 2.19 and tus server 2.3 for resumable file upload

routes.rb

```<code>  mount Tus::Server => '/files'
</code>```

model, file_resource.rb

```<code>class FileResource < ApplicationRecord
  # adds an `file` virtual attribute
  include ResumableFileUploader::Attachment.new(:file)
</code>```

controllers/files_controller.rb

```<code>def create
      file = FileResource.new(permitted_params)
      ...
      file.save
</code>```

config/initializers/shrine.rb

```<code>
s3_options = {
  bucket: ENV['S3_MEDIA_BUCKET_NAME'],
  access_key_id: ENV['S3_ACCESS_KEY'],
  secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
  region: ENV['S3_REGION']
}

Shrine.storages = {
  cache: Shrine::Storage::S3.new(prefix: 'file_library/shrine_cache', **s3_options),
  store: Shrine::Storage::S3.new(**s3_options), # public: true,
  tus: Shrine::Storage::Tus.new
}

Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data
</code>```

config/initializers/tus.rb

```<code>Tus::Server.opts[:storage] = Tus::Storage::S3.new(
  prefix: 'file_library',
  bucket: ENV['S3_MEDIA_BUCKET_NAME'],
  access_key_id: ENV['S3_ACCESS_KEY'],
  secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
  region: ENV['S3_REGION'],
  retry_limit: 3
)
Tus::Server.opts[:redirect_download] = true
</code>```

My issue is I cannot override the generate_location method of Shrine class to store the files in different folder structure in AWS s3.

All the files are created inside s3://bucket/file_library/ (the prefix provided in tus.rb). I want something like s3://bucket/file_library/:user_id/:parent_id/ folder structure.

I found that Tus configuration overrides all my resumable_file_uploader class custom options and have no effect on uploading.

resumable_file_uploader.rb

```<code>class ResumableFileUploader < Shrine
  plugin :validation_helpers  # NOT WORKS
  plugin :pretty_location     # NOT WORKS

  def generate_location(io, context = {})  # NOT WORKS
    f = context[:record]
    name = super # the default unique identifier

    puts "<<<<<<<<<<<<<<<<<<<<<<<<<<<<"*10

    ['users', f.author_id, f.parent_id, name].compact.join('/')
  end

  Attacher.validate do                    # NOT WORKS
    validate_max_size 15 * 1024 * 1024, message: 'is too large (max is 15 MB)'
  end

end
</code>```

So how can I create custom folder structure in S3 using tus options (as shrine options not works)?

答:
A tus server upload doesn't touch Shrine at all, so the #generate_location won't be called, but instead the tus-ruby-server decides the location.

Note that the tus server should only act as a temporary storage, you should still use Shrine to copy the file to a permanent storage (aka "promote"), just like with regular direct uploads. On promotion the #generate_location method will be called, so the file will be copied to the desired location; this all happens automatically with default Shrine setup.

Body:
I am using rails 5.2, Shrine 2.19 and tus server 2.3 for resumable file upload

routes.rb

  mount Tus::Server => '/files'

model, file_resource.rb

class FileResource < ApplicationRecord
  # adds an `file` virtual attribute
  include ResumableFileUploader::Attachment.new(:file)

controllers/files_controller.rb

def create
      file = FileResource.new(permitted_params)
      ...
      file.save

config/initializers/shrine.rb

s3_options = {
  bucket: ENV['S3_MEDIA_BUCKET_NAME'],
  access_key_id: ENV['S3_ACCESS_KEY'],
  secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
  region: ENV['S3_REGION']
}

Shrine.storages = {
  cache: Shrine::Storage::S3.new(prefix: 'file_library/shrine_cache', **s3_options),
  store: Shrine::Storage::S3.new(**s3_options), # public: true,
  tus: Shrine::Storage::Tus.new
}

Shrine.plugin :activerecord
Shrine.plugin :cached_attachment_data

config/initializers/tus.rb

Tus::Server.opts[:storage] = Tus::Storage::S3.new(
  prefix: 'file_library',
  bucket: ENV['S3_MEDIA_BUCKET_NAME'],
  access_key_id: ENV['S3_ACCESS_KEY'],
  secret_access_key: ENV['S3_SECRET_ACCESS_KEY'],
  region: ENV['S3_REGION'],
  retry_limit: 3
)
Tus::Server.opts[:redirect_download] = true

My issue is I cannot override the generate_location method of Shrine class to store the files in different folder structure in AWS s3.

All the files are created inside s3://bucket/file_library/ (the prefix provided in tus.rb). I want something like s3://bucket/file_library/:user_id/:parent_id/ folder structure.

I found that Tus configuration overrides all my resumable_file_uploader class custom options and have no effect on uploading.

resumable_file_uploader.rb

class ResumableFileUploader < Shrine
  plugin :validation_helpers  # NOT WORKS
  plugin :pretty_location     # NOT WORKS

  def generate_location(io, context = {})  # NOT WORKS
    f = context[:record]
    name = super # the default unique identifier

    puts "<<<<<<<<<<<<<<<<<<<<<<<<<<<<"*10

    ['users', f.author_id, f.parent_id, name].compact.join('/')
  end

  Attacher.validate do                    # NOT WORKS
    validate_max_size 15 * 1024 * 1024, message: 'is too large (max is 15 MB)'
  end

end

So how can I create custom folder structure in S3 using tus options (as shrine options not works)?


问:
Javascript regexp problem
I'm trying to use a pattern like this in a javascript regexp:

```<code>"foo.bar".match(/foo\.(buz|bar)/)
</code>```

but instead of returning foo.bar as I expect, it returns an array:

```<code>["foo.bar", "bar"]
</code>```

I don't get it. How do I match foo.bar and foo.buz?

答:
You are correctly matching "foo.bar" or "foo.buz", but since you have a grouping ((...)), the returned array includes more than one item:

[Full Match, Match 1, Match 2, ... , Match N]

According to the spec, the result is always an array, and the full matched text will be element 0.  Elements 1...N will be the matches (in your case, "bar" or "buz").

If you want make sure your array is length 1, then you want to put ?: after every ( to make it a non-capturing group (See https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions, syntax (?:x)):

```<code>"foo.bar".match(/foo\.(?:buz|bar)/)
</code>```

However, this is not necessary, as you can always just reference result[0] for the full match.

Incidentally, the /g option (see the docs again) will also get rid of the capturing groups from the result array.  Because /g executes a global search, the elements in the result array are used to display all full matches (and in your case given, there's just one).

Title: Javascript regexp problem

Body:
I'm trying to use a pattern like this in a javascript regexp:

"foo.bar".match(/foo\.(buz|bar)/)

but instead of returning foo.bar as I expect, it returns an array:

["foo.bar", "bar"]

I don't get it. How do I match foo.bar and foo.buz?

Body:
You are correctly matching "foo.bar" or "foo.buz", but since you have a grouping ((...)), the returned array includes more than one item:

[Full Match, Match 1, Match 2, ... , Match N]

According to the spec, the result is always an array, and the full matched text will be element 0.  Elements 1...N will be the matches (in your case, "bar" or "buz").

If you want make sure your array is length 1, then you want to put ?: after every ( to make it a non-capturing group (See https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions, syntax (?:x)):

"foo.bar".match(/foo\.(?:buz|bar)/)

However, this is not necessary, as you can always just reference result[0] for the full match.

Incidentally, the /g option (see the docs again) will also get rid of the capturing groups from the result array.  Because /g executes a global search, the elements in the result array are used to display all full matches (and in your case given, there's just one).