battle programmers alliance
Would you like to react to this message? Create an account in a few clicks or log in to continue.

battle programmers allianceLog in

the LivinGrimoire Artificial General Intelligence software design pattern forum

android mobile app development grimoire

power_settings_newLogin to reply
3 posters

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio finger print authentication walkthrough

more_horiz
android mobile app development grimoire - Page 4 2ii2el

1 add <uses-permission android:name="android.permission.USE_FINGERPRINT" />
to AndroidManifest.xml


2 add finger.png an icon to res/drawable (do not choose 24 when it asks U)


3 add FingerprintHandler.java :

Code:

package com.yotamarker.fingerauth1;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.fingerprint.FingerprintManager;
import android.os.CancellationSignal;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;

public class FingerprintHandler extends
        FingerprintManager.AuthenticationCallback {

    private CancellationSignal cancellationSignal;
    private Context appContext;

    public FingerprintHandler(Context context) {
        appContext = context;
    }

    public void startAuth(FingerprintManager manager,
                          FingerprintManager.CryptoObject cryptoObject) {

        cancellationSignal = new CancellationSignal();

        if (ActivityCompat.checkSelfPermission(appContext,
                Manifest.permission.USE_FINGERPRINT) !=
                PackageManager.PERMISSION_GRANTED) {
            return;
        }
        manager.authenticate(cryptoObject, cancellationSignal, 0, this, null);
    }

    @Override
    public void onAuthenticationError(int errMsgId,
                                      CharSequence errString) {
        Toast.makeText(appContext,
                "Authentication error\n" + errString,
                Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAuthenticationHelp(int helpMsgId,
                                     CharSequence helpString) {
        Toast.makeText(appContext,
                "Authentication help\n" + helpString,
                Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAuthenticationFailed() {
        Toast.makeText(appContext,
                "Authentication failed.",
                Toast.LENGTH_LONG).show();
    }

    @Override
    public void onAuthenticationSucceeded(
            FingerprintManager.AuthenticationResult result) {

        Toast.makeText(appContext,
                "Authentication succeeded.",
                Toast.LENGTH_LONG).show();
    }

}


key note : in  public void onAuthenticationSucceeded(){
place the code you want to run when the print is authed successfully

4 MainActivity.java :

Code:

package com.yotamarker.fingerauth1;



//public class MainActivity extends AppCompatActivity {

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.KeyguardManager;
import android.hardware.fingerprint.FingerprintManager;
import android.widget.Toast;
import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.security.keystore.KeyProperties;
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.KeyPermanentlyInvalidatedException;

import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import java.security.InvalidAlgorithmParameterException;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStoreException;
import java.security.UnrecoverableKeyException;

import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.Cipher;

public class MainActivity extends AppCompatActivity {

    private Cipher cipher;
    private static final String KEY_NAME = "example_key";
    private FingerprintManager fingerprintManager;
    private KeyguardManager keyguardManager;
    private KeyStore keyStore;
    private KeyGenerator keyGenerator;
    private FingerprintManager.CryptoObject cryptoObject;

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

        if (getManagers()) {
            generateKey();

            if (cipherInit()) {
                cryptoObject =
                        new FingerprintManager.CryptoObject(cipher);
                FingerprintHandler helper = new FingerprintHandler(this);
                helper.startAuth(fingerprintManager, cryptoObject);

            }
        }

    }

    protected void generateKey() {
        try {
            keyStore = KeyStore.getInstance("AndroidKeyStore");
        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            keyGenerator = KeyGenerator.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES,
                    "AndroidKeyStore");
        } catch (NoSuchAlgorithmException |
                NoSuchProviderException e) {
            throw new RuntimeException(
                    "Failed to get KeyGenerator instance", e);
        }

        try {
            keyStore.load(null);
            keyGenerator.init(new
                    KeyGenParameterSpec.Builder(KEY_NAME,
                    KeyProperties.PURPOSE_ENCRYPT |
                            KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)
                    .setEncryptionPaddings(
                            KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
            keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException |
                InvalidAlgorithmParameterException
                | CertificateException | IOException e) {
            throw new RuntimeException(e);
        }

    }

    public boolean cipherInit() {
        try {
            cipher = Cipher.getInstance(
                    KeyProperties.KEY_ALGORITHM_AES + "/"
                            + KeyProperties.BLOCK_MODE_CBC + "/"
                            + KeyProperties.ENCRYPTION_PADDING_PKCS7);
        } catch (NoSuchAlgorithmException |
                NoSuchPaddingException e) {
            throw new RuntimeException("Failed to get Cipher", e);
        }

        try {
            keyStore.load(null);
            SecretKey key = (SecretKey) keyStore.getKey(KEY_NAME,
                    null);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            return true;
        } catch (KeyPermanentlyInvalidatedException e) {
            return false;
        } catch (KeyStoreException | CertificateException
                | UnrecoverableKeyException | IOException
                | NoSuchAlgorithmException | InvalidKeyException e) {
            throw new RuntimeException("Failed to init Cipher", e);
        }
    }
    private Boolean getManagers() {
        keyguardManager =
                (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
        fingerprintManager =
                (FingerprintManager)
                        getSystemService(FINGERPRINT_SERVICE);

        if (!keyguardManager.isKeyguardSecure()) {

            Toast.makeText(this,
                    "Lock screen security not enabled in Settings",
                    Toast.LENGTH_LONG).show();
            return false;
        }

        if (ActivityCompat.checkSelfPermission(this,
                Manifest.permission.USE_FINGERPRINT) !=
                PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(this,
                    "Fingerprint authentication permission not enabled",
                    Toast.LENGTH_LONG).show();

            return false;
        }

        if (!fingerprintManager.hasEnrolledFingerprints()) {

            // This happens when no fingerprints are registered.
            Toast.makeText(this,
                    "Register at least one fingerprint in Settings",
                    Toast.LENGTH_LONG).show();
            return false;
        }
        return true;
    }
}


5 activity_main.xml (the UserInterface (screen)) :

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_marginTop="200dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/finger" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="52dp"
        android:text="Touch Sensor"
        android:layout_gravity="center"
        android:textSize="24sp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

</LinearLayout>



shimmon no jutsu  :tu:

Last edited by Moti Barski on Wed Oct 10, 2018 2:06 am; edited 1 time in total

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid srudio read SMS walkthrough with ask permission dialog

more_horiz
android mobile app development grimoire - Page 4 2iknxl

AndroidManifest.xml : add :
<uses-permission android:name="android.permission.READ_SMS" />

MainActivity.java

Code:

package com.yotamarker.readsms2;

import android.Manifest;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    final int READ_SMS = 6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //TextView view = new TextView(this);
        ReadSMSPermission();
        Uri uriSMSURI = Uri.parse("content://sms/inbox");
        Cursor cur = getContentResolver().query(uriSMSURI, null, null, null,null);
        String sms = "";
        while (cur.moveToNext()) {
            sms += "From :" + cur.getString(2) + " : " + cur.getString(12)+"\n";
        }
        Toast.makeText(this,sms,Toast.LENGTH_LONG).show();
    }
    public void ReadSMSPermission(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CALL_PHONE)) {

            new AlertDialog.Builder(this)
                    .setTitle("Permission needed")
                    .setMessage("This permission is needed to read SMSes")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.READ_SMS}, READ_SMS);
                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create().show();

        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_SMS}, READ_SMS);

        }
    }
    }


note : I played with the numbers at this code line to get the message body :
sms += "From :" + cur.getString(2) + " : " + cur.getString(12)+"\n";

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio get device temperature

more_horiz
android mobile app development grimoire - Page 4 2ilp84

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    tools:context="com.yotamarker.sensors.MainActivity">

    <TextView
        android:id="@+id/textViewBatteryTemp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:textAppearance="?android:attr/textAppearanceLarge" />

    <Button
        android:id="@+id/buttonBatteryTemp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textViewBatteryTemp"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="16dp"
        android:text="Click here to Get battery temperature" />
</RelativeLayout>


MainActivity.java :

Code:

package com.yotamarker.sensors;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;


public class MainActivity extends Activity {

    TextView tempTextView;
    Button button;
    IntentFilter intentfilter;
    float batteryTemp;
    String currentBatterytemp="Current Battery temp :";
    int batteryLevel;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        button = (Button)findViewById(R.id.buttonBatteryTemp);
        tempTextView = (TextView)findViewById(R.id.textViewBatteryTemp);

        intentfilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);

        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                MainActivity.this.registerReceiver(broadcastreceiver,intentfilter);

            }
        });

    }

    private BroadcastReceiver broadcastreceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {


            batteryTemp = (float)(intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE,0))/10;

            tempTextView.setText(currentBatterytemp +" "+batteryTemp +" "+ (char) 0x00B0 +"C");

        }
    };


}


ondouken

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio receive SMS at realtime and interface listener explaination

more_horiz
android mobile app development grimoire - Page 4 2ip6fl

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/txt1"
        />

</android.support.constraint.ConstraintLayout>


interface SmsEventListener :

Code:

public interface SmsEventListener {
    void messageReceived(SmsInfo smsInfo);
}


SmsInfo.java :

(holds the SmsInfo) :

Code:

package com.yotamarker.receivesms;

import java.util.Date;

public class SmsInfo {
    private String sender;
    private String body;
    private Date date;

    public SmsInfo(String sender, String body, Date date) {
        this.sender = sender;
        this.body = body;
        this.date = date;
    }

    public String getSender() {
        return sender;
    }

    public String getBody() {
        return body;
    }

    public Date getDate() {
        return date;
    }
}


SmsBroadcastReceiver.java :

Code:

package com.yotamarker.receivesms;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;

import java.util.Date;

/**

 * A broadcast receiver who listens for incoming SMS

 */



public class SmsBroadcastReceiver extends BroadcastReceiver {
    private SmsEventListener smsEventListener;

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle myBundle = intent.getExtras();

        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED")) {
            Bundle bundle = intent.getExtras();
            SmsMessage[] msgs = null;
            String sender;
            if (bundle != null) {

                try {
                    Object[] pdus = (Object[]) bundle.get("pdus");
                    msgs = new SmsMessage[pdus.length];
                    for (int i = 0; i < msgs.length; i++) {
                        String format = myBundle.getString("format");

                        msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i], format);
                        sender = msgs[i].getOriginatingAddress();
                        String body = msgs[i].getMessageBody();
                        Long timeStamp = msgs[i].getTimestampMillis();
                        Date date = new Date(timeStamp);

                        smsEventListener.messageReceived(new SmsInfo(sender, body, date));

                    }
                } catch (Exception e) {
                    // Possible NullPointerException
                }
            }
        }
    }
public void setSmsEventListener(SmsEventListener smsEventListener){
        this.smsEventListener = smsEventListener;
}
}


MainActivity.java :

Code:

package com.yotamarker.receivesms;

import android.Manifest;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.provider.Telephony;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements  SmsEventListener{
    final int RECEIVE_SMS = 22;
    final int READ_SMS = 6;
    private  SmsBroadcastReceiver smsBroadcastReceiver;
    TextView tv1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setPointer();
    }

    private void setPointer() {
        tv1 = findViewById(R.id.txt1);
        RECEIVESMSPermission();
        ReadSMSPermission();
        smsBroadcastReceiver = new SmsBroadcastReceiver();
        setRecivers();
    }

    private void setRecivers() {
        registerReceiver(smsBroadcastReceiver, new IntentFilter(Telephony.Sms.Intents.SMS_RECEIVED_ACTION));
        smsBroadcastReceiver.setSmsEventListener(this);
    }

    public void RECEIVESMSPermission(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CALL_PHONE)) {

            new AlertDialog.Builder(this)
                    .setTitle("Permission needed")
                    .setMessage("This permission is needed to receive SMSes")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.RECEIVE_SMS}, RECEIVE_SMS);
                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create().show();

        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.RECEIVE_SMS}, RECEIVE_SMS);

        }
    }
    public void ReadSMSPermission(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.CALL_PHONE)) {

            new AlertDialog.Builder(this)
                    .setTitle("Permission needed")
                    .setMessage("This permission is needed to read SMSes")
                    .setPositiveButton("ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[]{Manifest.permission.READ_SMS}, READ_SMS);
                        }
                    })
                    .setNegativeButton("cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            dialog.dismiss();
                        }
                    })
                    .create().show();

        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_SMS}, READ_SMS);

        }
    }

    @Override
    public void messageReceived(SmsInfo smsInfo) {
        tv1.setText(smsInfo.getSender() + "\n"+smsInfo.getBody()+"\n"+smsInfo.getDate().toString());
        Toast.makeText(this,smsInfo.getBody(),Toast.LENGTH_LONG).show();
    }
}



notes :
general steps to create a listener :
create an interface, glue it to the object (and implement the method), shallow clone send the object to the special class with the special ability (SMS in this example)and object.interfaceMethode in said class


finally in the object (main activity) :

registerReceiver(shallow clone object, new IntentFilter(sp ability));

similar to the façade design pattern with the difference that it is needed to fill in the interface methodes

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio set APK icon walkthrough

more_horiz

android mobile app development grimoire - Page 4 2ipeon

Go to AndroidManifest.xml
In the tag, look for android:icon tag.
Copy and paste your icon in drawable folder(available in res folder of your project).
Set the value of android:icon tag as
android:icon="@drawable/youriconname"
Voila! you are done. Save the changes and test.

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio toggle flashlight and blink it

more_horiz
android mobile app development grimoire - Page 4 2irzgx

AndroidManifest.xml :

<uses-permission android:name="android.permission.CAMERA" />
   <uses-feature android:name="android.hardware.camera" />

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnFlashLightToggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="FLASHLIGHT OFF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btnBlinkFlashLight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="24dp"
        android:text="BLINK FLASHLIGHT"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/btnFlashLightToggle" />


</android.support.constraint.ConstraintLayout>


MainActivity.java :

Code:

package com.yotamarker.flashlight;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    Button btnFlashLight, btnBlinkFlashLight;
    private static final int CAMERA_REQUEST = 123;
    boolean hasCameraFlash = false;

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


        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST);

        hasCameraFlash = getPackageManager().
                hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

        btnFlashLight = findViewById(R.id.btnFlashLightToggle);
        btnBlinkFlashLight = findViewById(R.id.btnBlinkFlashLight);

        btnFlashLight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (hasCameraFlash) {
                    if (btnFlashLight.getText().toString().contains("ON")) {
                        btnFlashLight.setText("FLASHLIGHT OFF");
                        btnBlinkFlashLight.setText("BLINK FLASHLIGHT OFF");
                        flashLightOff();
                    } else {
                        btnBlinkFlashLight.setText("BLINK FLASHLIGHT ON");
                        btnFlashLight.setText("FLASHLIGHT ON");
                        flashLightOn();
                    }
                } else {
                    Toast.makeText(MainActivity.this, "No flash available on your device",
                            Toast.LENGTH_SHORT).show();
                }
            }
        });

        btnBlinkFlashLight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                if(btnFlashLight.getText().toString().contains("ON"))
                {
                    blinkFlash();
                }
                else{
                    Toast.makeText(MainActivity.this, "Press the above button first.",
                            Toast.LENGTH_SHORT).show();
                }

            }
        });


    }

    private void flashLightOn() {
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);

        try {
            String cameraId = cameraManager.getCameraIdList()[0];
            cameraManager.setTorchMode(cameraId, true);
        } catch (CameraAccessException e) {
        }
    }

    private void flashLightOff() {
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        try {
            String cameraId = cameraManager.getCameraIdList()[0];
            cameraManager.setTorchMode(cameraId, false);
        } catch (CameraAccessException e) {
        }
    }

    private void blinkFlash()
    {
        CameraManager cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        String myString = "0101010101";
        long blinkDelay = 50; //Delay in ms
        for (int i = 0; i < myString.length(); i++) {
            if (myString.charAt(i) == '0') {
                try {
                    String cameraId = cameraManager.getCameraIdList()[0];
                    cameraManager.setTorchMode(cameraId, true);
                } catch (CameraAccessException e) {
                }
            } else {
                try {
                    String cameraId = cameraManager.getCameraIdList()[0];
                    cameraManager.setTorchMode(cameraId, false);
                } catch (CameraAccessException e) {
                }
            }
            try {
                Thread.sleep(blinkDelay);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case CAMERA_REQUEST:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    hasCameraFlash = getPackageManager().
                            hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
                } else {
                    btnFlashLight.setEnabled(false);
                    btnBlinkFlashLight.setEnabled(false);
                    Toast.makeText(MainActivity.this, "Permission Denied for the Camera", Toast.LENGTH_SHORT).show();
                }
                break;
        }
    }
}


hadouken :saber:

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio event bus walkthrough

more_horiz
android mobile app development grimoire - Page 4 2isa6h

eventBus is a very fast way to run threads that send strings and run methodes on activities
and other components. it is also shorter to write compared to regular services.

in build.gradle(module:app) add dependency :

implementation 'org.greenrobot:eventbus:3.1.1'

add POJO type class (the MSG container):

Code:

package com.yotamarker.eventbus3;

public class NameEvent {
    private String name;

    public NameEvent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}


add the eventbus service :

Code:

package com.yotamarker.eventbus3;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;

import org.greenrobot.eventbus.EventBus;

public class EventBusService extends Service {
    private static final String[] items = {
            "Moti Moti", "ichi", "ni", "san",
            "yon", "go", "ippen shinde miru ?"
    };
    Thread motiMoti;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        motiMoti = new LoadNamesThread();
        motiMoti.start();
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {
        motiMoti.interrupt();
        super.onDestroy();
    }

    class LoadNamesThread extends Thread {
        @Override
        public void run() {
            for (String item : items) {
                if (!isInterrupted()) {
                    EventBus.getDefault().post(new NameEvent(item));
                    MainActivity.arthur.post(new NameEvent(item));
                    SystemClock.sleep(4000);

                }
                else
                {
                    break;
                }
            }
        }
    }

}


MainActivity :

Code:

package com.yotamarker.eventbus3;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

public class MainActivity extends AppCompatActivity {
    static EventBus arthur;

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

        //create an intent the will fire up our service
        Intent intent = new Intent(this, EventBusService.class);
        //just start the service
        arthur = new EventBus();
        startService(intent);


    }

    @Override
    protected void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    protected void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onNameEvent(NameEvent event) {
        Toast.makeText(this, event.getName(), Toast.LENGTH_SHORT).show();
    }

    @Subscribe (threadMode = ThreadMode.MAIN)
    public void onNameEventLog(NameEvent event)
    {
        Log.e("Tag", "onNameEventLog: "+event.getName());
    }

}


finally register the service in AndroidManifest :

<service android:name=".EventBusService"/>

so it looks like :

Code:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yotamarker.eventbus3">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service android:name=".EventBusService"/>
    </application>
</manifest>


notes :

return START_NOT_STICKY; means the service will not run after fininished or
after the phone has been restarted

Toast.makeText(this, event.getName(), Toast.LENGTH_SHORT).show(); is the code triggered
by the bus service with event.getName

corresponding to MainActivity.arthur.post(new NameEvent(item)); on the bus

for more : https://github.com/greenrobot/EventBus

:tokushushoukan

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio auto complete textbox

more_horiz
android mobile app development grimoire - Page 4 2iy4gc

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


    <AutoCompleteTextView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/txtCities"
        />

</android.support.constraint.ConstraintLayout>


MainActivity.java :

Code:

package com.yotamarker.simstuff1;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    String[] cities = {"TLV","bat-yam","yafo","holon"};
    AutoCompleteTextView ACT;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,R.layout.support_simple_spinner_dropdown_item,cities);
        ACT = findViewById(R.id.txtCities);
        ACT.setThreshold(3); // how many chars will trigger the auto complete
        ACT.setAdapter(adapter);
    }
}


kanseiken :bmb:

descriptionandroid mobile app development grimoire - Page 4 Emptycheck is NFC available

more_horiz

Code:

private Boolean IsNFCPresent() {
        return  getPackageManager().hasSystemFeature(PackageManager.FEATURE_NFC);
    }


note you can change .FEATURE_NFC to check on other feature availabilities :o

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio get url source code with contents and stuff

more_horiz
android mobile app development grimoire - Page 4 2j0gvb

main :

Code:

package com.yotamarker.sitecontents;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class MainActivity extends AppCompatActivity {
    TextView txt1;
    private String xmlString = "";
    private final String XML_URL = "https://www.yotamarker.com";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txt1 = findViewById(R.id.txtOne);
        getDataJSON();
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        txt1.setText(xmlString);

    }

    public void getDataJSON() {
        //we never use void in AsyncTask, we need to use Void
        new AsyncTask<Void, Void, String>() {
            @Override
            protected String doInBackground(Void... voids) {
                //we need to open HTTP URL Connection to our desired URL (www.boi.org.il)
                HttpURLConnection connection = null;
                try {
                    connection = (HttpURLConnection) new URL(XML_URL).openConnection();
                    BufferedReader buf = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                    String line;
                    while ((line = buf.readLine()) != null) {
                        xmlString += line;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    connection.disconnect();
                }

                return xmlString;
            }

            @Override
            protected void onPostExecute(String jsonString) {
                super.onPostExecute(jsonString);
                http://Log.e("XML", "onPostExecute: " + jsonString);
                // display json string
                Toast.makeText(getApplicationContext(), jsonString, Toast.LENGTH_LONG).show();

            }
        }.execute();
    }
}


main xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/txtOne"/>

</android.support.constraint.ConstraintLayout>

add manifest permission :
<uses-permission android:name="android.permission.INTERNET"/>
:chai:

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio filter debugger logcat filter

more_horiz
android mobile app development grimoire - Page 4 2j3mbz

logcat (debug) output filter :
in logcat next to the regex checkbox choose, editfilter configuration

to moniter a code line like this (does it run) :
Log.i("hadoken", "motiiiiiiiiiiiiiiiiiiiiiiiii");
set the Log tag to hadouken

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio volume meter from microphone at real time

more_horiz
android mobile app development grimoire - Page 4 2jb053



android studio volume meter from microphone at real time

add those classes :

1 :

Code:

//
// PFont.java - pseudo PFont implementation.
//
// github:
//      yoggy / PseudoP5View
//      https://github.com/yoggy/PseudoP5View
//
//  license:
//      Copyright (c) 2015 yoggy <yoggy0@gmail.com>
//      Released under the MIT license
//      http://opensource.org/licenses/mit-license.php
//
package com.yotamarker.vumeter3;

public class PFont {

 String fontname;
 int size;

 public PFont(String fontname, int size) {
 this.fontname = fontname;
 this.size = size;
 }

 String getFontName() {
 return fontname;
 }

 int getSize() {
 return size;
 }

}


2 :

Code:

//
// PseudoP5View.java - a view implementation like PApplet class in processing.org.  
//
// github:
//      yoggy / PseudoP5View
//      https://github.com/yoggy/PseudoP5View
//
//  license:
//      Copyright (c) 2015 yoggy <yoggy0@gmail.com>
//      Released under the MIT license
//      http://opensource.org/licenses/mit-license.php
//
//  example;
//     public class SampleView extends PseudoP5View {
//         public SampleView(Context context) {
//             super(context);
//         }
//        
//         @Override
//         protected void setup() {
//             size(640, 480);
//             frameRate(30);
//         }
//    
//         @Override
//         protected void draw() {
//             background(0, 0, 0);
//            
//             noStroke();
//             fill(255, 255, 255);
//    
//             for (int i = 0; i < 100; ++i) {
//                 float x = random(width);
//                 float y = random(height);
//                 ellipse(x, y, 20, 20);
//             }
//         }
//     }
//
package com.yotamarker.vumeter3;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public abstract class PseudoP5View extends SurfaceView implements
 SurfaceHolder.Callback {

 /////////////////////////////////////////////////////////////////////////////
 //
 // processing like variables (protected)
 //
 /////////////////////////////////////////////////////////////////////////////
 protected int width;
 protected int height;
 protected int frameCount;
 protected float frameRate;
 protected float mouseX;
 protected float mouseY;
 protected boolean mousePressed;

 public static final float PI = (float) Math.PI;
 public static final int CENTER = 1;

 /////////////////////////////////////////////////////////////////////////////
 //
 // processing like functions (protected)
 //
 /////////////////////////////////////////////////////////////////////////////

 protected abstract void setup();

 protected abstract void draw();

 //
 // for events
 //
 protected void mousePressed() {
 }

 protected void mouseReleased() {
 }

 //
 // for sketch settings
 //
 protected void size(int width, int height) {
 this.width = width;
 this.height = height;
 }

 protected void frameRate(int fps) {
 frame_rate = fps;

 frameRate = fps;
 frame_rate_counter_ = 0;
 }

 //
 // for draw
 //
 protected void background(int color) {
 if (cc == null)
 return;

 resetSketchScale();

 Paint p = new Paint();
 p.setColor(color | 0xff000000);
 cc.drawRect(new Rect(0, 0, getWidth(), getHeight()), p);

 adjustSketchScale();
 }

 protected void background(int r, int g, int b) {
 background(rgb2Int(r, g, b));
 }

 protected void strokeWeight(float weight) {
 current_stroke_w = weight;
 }

 protected void noFill() {
 enable_fill = false;
 }

 protected void fill(int c) {
 fill(c, c, c, 255);
 }

 protected void fill(int c, int a) {
 fill(c, c, c, a);
 }

 protected void fill(int r, int g, int b) {
 fill(r, g, b, 255);
 }

 protected void fill(int r, int g, int b, int a) {
 fillImpl(rgb2Int(r, g, b), a);
 }

 protected void noStroke() {
 enable_stroke = false;
 }

 protected void stroke(int c) {
 stroke(c, c, c, 255);
 }

 protected void stroke(int r, int g, int b) {
 stroke(r, g, b, 255);
 }

 protected void stroke(int c, int a) {
 stroke(c, c, c, a);
 }

 protected void stroke(int r, int g, int b, int a) {
 strokeImpl(rgb2Int(r, g, b), a);
 }

 protected void line(int x1, int y1, int x2, int y2) {
 if (enable_stroke) {
 cc.drawLine(x1, y1, x2, y2, getStrokePaint());
 }
 }

 protected void line(float x1, float y1, float x2, float y2) {
 if (enable_stroke) {
 cc.drawLine(x1, y1, x2, y2, getStrokePaint());
 }
 }

 protected void rect(float x, float y, float w, float h) {
 if (enable_fill) {
 cc.drawRect(createRectF(x, y, w, h), getFillPaint());
 }
 if (enable_stroke) {
 cc.drawRect(createRectF(x, y, w, h), getStrokePaint());
 }
 }

 protected void rect(float x, float y, float w, float h, float r) {
 if (enable_fill) {
 cc.drawRoundRect(createRectF(x, y, w, h), r, r, getFillPaint());
 }
 if (enable_stroke) {
 cc.drawRoundRect(createRectF(x, y, w, h), r, r, getStrokePaint());
 }
 }

 protected void ellipse(float x, float y, float w, float h) {
 RectF r = createRectF(x - w / 2, y - h / 2, w, h);

 if (enable_fill) {
 cc.drawOval(r, getFillPaint());
 }
 if (enable_stroke) {
 cc.drawOval(r, getStrokePaint());
 }
 }

 protected void bezier(float x1, float y1, float x2, float y2, float x3,
 float y3, float x4, float y4) {
 beginShape();
 vertex(x1, y1);
 bezierVertex(x2, y2, x3, y3, x4, y4);
 endShape();
 }

 Path current_path = null;
 int current_path_vertex_num = 0;

 protected void beginShape() {
 current_path = new Path();
 current_path_vertex_num = 0;
 }

 protected void vertex(float x, float y) {
 if (current_path == null)
 return;

 if (current_path_vertex_num == 0) {
 current_path.moveTo(x, y);
 } else {
 current_path.lineTo(x, y);
 }
 current_path_vertex_num++;
 }

 protected void bezierVertex(float x2, float y2, float x3, float y3,
 float x4, float y4) {
 if (current_path == null)
 return;

 current_path.cubicTo(x2, y2, x3, y3, x4, y4);

 current_path_vertex_num++;
 }

 protected void endShape() {
 if (current_path == null)
 return;

 if (enable_fill) {
 cc.drawPath(current_path, getFillPaint());
 }
 if (enable_stroke) {
 cc.drawPath(current_path, getStrokePaint());
 }
 }

 //
 // for text drawing
 //
 PFont current_pfont = new PFont("dummy", 12);

 protected PFont createFont(String fontname, int size) {
 PFont pfont = new PFont(fontname, size);
 return pfont;
 }

 protected void textFont(PFont pfont) {
 this.current_pfont = pfont;
 }

 protected void text(String str, float x, float y) {
 Paint p = getFillPaint();
 p.setTextSize(this.current_pfont.getSize());
 cc.drawText(str, x, y, p);
 }

 // matrix operations
 protected void pushMatrix() {
 cc.save();
 }

 protected void popMatrix() {
 cc.restore();
 }

 protected void translate(float dx, float dy) {
 cc.translate(dx, dy);
 }

 protected void rotate(float rad) {
 float deg = rad / (float) Math.PI * 180.0f;
 cc.rotate(deg);
 }

 protected void scale(float s) {
 scale(s, s);
 }

 protected void scale(float sx, float sy) {
 cc.scale(sx, sy);
 }

 //
 // utilities
 //
 protected String nfs(int val, int digit) {
 String zero = "";
 for (int i = 0; i < digit; ++i) {
 zero += 0;
 }

 String tmp = zero + Integer.toString(val);
 String result = tmp.substring(tmp.length() - digit, tmp.length());
 return result;
 }

 protected int unhex(String str) {
 return Integer.parseInt(str, 16);
 }

 protected float random(float range) {
 float r = (float) (Math.random() * range);
 return r;
 }

 public float random(float v0, float v1) {
 float diff = v1 - v0;
 float rv = random(diff) + v0;
 return rv;
 }

 protected float cos(float t) {
 return (float) Math.cos(t);
 }

 protected float sin(float t) {
 return (float) Math.sin(t);
 }

 protected float abs(float val) {
 return Math.abs(val);
 }

 protected void println(String str) {
 Log.d(getClass().getName(), str);
 }

 protected void print(String str) {
 Log.d(getClass().getName(), str);
 }

 /////////////////////////////////////////////////////////////////////////////
 //
 // private variables
 //
 /////////////////////////////////////////////////////////////////////////////
 protected Canvas cc;

 int frame_rate = 30;
 int frame_rate_counter_;
 long frame_rate_counter_start_time_;
 float screen_offset_scale;
 float screen_offset_x;
 float screen_offset_y;

 Matrix initial_matrix;

 boolean enable_stroke;
 int current_stroke_argb = 0xffffffff;
 float current_stroke_w = 1;

 boolean enable_fill;
 int current_fill_argb = 0xffffffff;

 boolean is_timer_enable = false;
 Thread draw_thread = null;

 /////////////////////////////////////////////////////////////////////////////
 //
 // constructor
 //
 /////////////////////////////////////////////////////////////////////////////
 public PseudoP5View(Context context) {
 super(context);
 getHolder().addCallback(this);
 }

 /////////////////////////////////////////////////////////////////////////////
 //
 // surface holder operations
 //
 /////////////////////////////////////////////////////////////////////////////
 SurfaceHolder surface_holder = null;

 @Override
 public void surfaceCreated(SurfaceHolder holder) {
 }

 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width,
                               int height) {
 surface_holder = holder;
 }

 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
 surface_holder = null;
 }

 /////////////////////////////////////////////////////////////////////////////
 //
 // draw thread (internal use only)
 //
 /////////////////////////////////////////////////////////////////////////////
 public void onResume() {
 timerStart();
 }

 public void onPause() {
 timerStop();
 mousePressed = false;
 }

 void timerStart() {
 is_timer_enable = true;

 draw_thread = new Thread(draw_task, "pseudo_p5_view_thread");
 draw_thread.start();
 }

 void timerStop() {
 is_timer_enable = false;
 try {
 draw_thread.join();
 } catch (InterruptedException e) {
 }
 draw_thread = null;
 }

 Runnable draw_task = new Runnable() {
 @Override
 public void run() {
 long st, draw_t;
 while (is_timer_enable) {
 if (surface_holder != null) {
 Canvas c = surface_holder.lockCanvas();
 st = System.currentTimeMillis();
 drawInternal(c);
 draw_t = System.currentTimeMillis() - st;
 surface_holder.unlockCanvasAndPost(c);
 } else {
 draw_t = 0;
 }

 long interval_t = (long) (1000 / frame_rate);
 long diff = interval_t - draw_t;
 if (diff > 0) {
 try {
 Thread.sleep(diff);
 } catch (InterruptedException e) {
 }
 }
 }
 }
 };

 protected void drawInternal(Canvas canvas) {
 this.cc = canvas;

 boolean rv = adjustSketchScale();
 if (rv == true) {
 draw();
 }
 cc.restore();

 frameCount++;

 frame_rate_counter_++;
 if (frame_rate_counter_ == 100) {
 double dt = (System.currentTimeMillis() - frame_rate_counter_start_time_) / 1000.0;
 double t = dt / 100;
 frameRate = (float) (1 / t);

 frame_rate_counter_ = 0;
 frame_rate_counter_start_time_ = System.currentTimeMillis();
 }
 }

 //
 //
 //
 public static final int PSEUDO_PORTRAIT_MODE_0 = 0;
 public static final int PSEUDO_PORTRAIT_MODE_90 = 1;
 public static final int PSEUDO_PORTRAIT_MODE_270 = 2;

 int pseudo_portrait_mode = PSEUDO_PORTRAIT_MODE_0;
 
 public void setPseudoPortraitMode(int val) {
 if (val < 0 || 2 < val) return;
 this.pseudo_portrait_mode = val;
 }
 
 private boolean adjustSketchScale() {
 cc.save();

 int view_w, view_h;
 if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_90) {
 view_w = getHeight();
 view_h = getWidth();
 }
 else if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_270) {
 view_w = getHeight();
 view_h = getWidth();
 }
 else {
 view_w = getWidth();
 view_h = getHeight();
 }

 if (view_w == 0 || view_h == 0)
 return false;
 if (width == 0 || height == 0)
 return false;

 float aspect_view = view_w / (float) view_h;
 float aspect_sketch = width / (float) height;

 if (aspect_view > aspect_sketch) {
 screen_offset_scale = view_h / (float) height;
 screen_offset_x = (view_w - width * screen_offset_scale) / 2;
 screen_offset_y = 0.0f;
 } else {
 screen_offset_scale = view_w / (float) width;
 screen_offset_x = 0.0f;
 screen_offset_y = (view_h - height * screen_offset_scale) / 2;
 }
 
 Matrix mat_trans = new Matrix();
 mat_trans.postTranslate(screen_offset_x, screen_offset_y);
 cc.concat(mat_trans);

 Matrix mat_scale = new Matrix();
 mat_scale.postScale(screen_offset_scale, screen_offset_scale);
 cc.concat(mat_scale);

 if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_90) {
 Matrix mat_rot = new Matrix();
 mat_rot.postRotate(90);
 cc.concat(mat_rot);

 Matrix mat_down_shift = new Matrix();
 mat_down_shift.postTranslate(0, -height);
 cc.concat(mat_down_shift);
 }
 else if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_270) {
 Matrix mat_rot = new Matrix();
 mat_rot.postRotate(-90);
 cc.concat(mat_rot);

 Matrix mat_down_shift = new Matrix();
 mat_down_shift.postTranslate(-width, 0);
 cc.concat(mat_down_shift);
 }
 return true;
 }

 void resetSketchScale() {
 cc.restore();
 }

 /////////////////////////////////////////////////////////////////////////////
 //
 // events
 //
 /////////////////////////////////////////////////////////////////////////////
 @SuppressLint("ClickableViewAccessibility")
 @Override
 public boolean onTouchEvent(MotionEvent evt) {
 float screen_x = evt.getX();
 float screen_y = evt.getY();

 if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_90) {
 screen_x = evt.getY();
 screen_y = getWidth() - evt.getX();
 }
 else if (pseudo_portrait_mode == PSEUDO_PORTRAIT_MODE_270) {
 screen_x = getHeight() - evt.getY();
 screen_y = evt.getX();
 }
 
 mouseX = (screen_x - screen_offset_x) / screen_offset_scale;
 mouseY = (screen_y - screen_offset_y) / screen_offset_scale;

 if (evt.getAction() == android.view.MotionEvent.ACTION_DOWN) {
 mousePressed = true;
 mousePressed();
 } else if (evt.getAction() == android.view.MotionEvent.ACTION_UP) {
 mousePressed = false;
 mouseReleased();
 }

 return true;
 }

 /////////////////////////////////////////////////////////////////////////////
 //
 // utils
 //
 /////////////////////////////////////////////////////////////////////////////
 void fillImpl(int c, int a) {
 enable_fill = true;
 current_fill_argb = c | ((a << 24) & 0xff000000);
 }

 void strokeImpl(int c, int a) {
 enable_stroke = true;
 current_stroke_argb = c | ((a << 24) & 0xff000000);
 }

 int rgb2Int(int r, int g, int b) {
 int c = ((r << 16) & 0x00ff0000) | ((g <<  & 0x0000ff00)
 | ((b << 0) & 0x000000ff) | 0x00000000;
 return c;
 }

 RectF createRectF(float x, float y, float w, float h) {
 RectF r = new RectF(x, y, x + w, y + h);
 return r;
 }

 Paint getFillPaint() {
 Paint p = new Paint();
 p.setStyle(Style.FILL);
 p.setColor(current_fill_argb);
 p.setAntiAlias(true);
 return p;
 }

 Paint getStrokePaint() {
 Paint p = new Paint();
 p.setStyle(Style.STROKE);
 p.setStrokeWidth(current_stroke_w);
 p.setColor(current_stroke_argb);
 p.setAntiAlias(true);
 return p;
 }
}


3 :

Code:

//
// PVector.java - pseudo PVector implementation.
//
// github:
//      yoggy / PseudoP5View
//      https://github.com/yoggy/PseudoP5View
//
//  license:
//      Copyright (c) 2015 yoggy <yoggy0@gmail.com>
//      Released under the MIT license
//      http://opensource.org/licenses/mit-license.php
//
package com.yotamarker.vumeter3;

import java.util.Random;

public class PVector {
 public float x;
 public float y;
 
 public PVector() {
 set(0.0f, 0.0f);
 }

 public PVector(int x, int y) {
 set(x, y);
 }

 public PVector(float x, float y) {
 set(x, y);
 }

 public PVector(double x, double y) {
 set(x, y);
 }

 public void set(int x, int y) {
 this.x = (float)x;
 this.y = (float)y;
 }
 
 public void set(float x, float y) {
 this.x = x;
 this.y = y;
 }

 public void set(double x, double y) {
 this.x = (float)x;
 this.y = (float)y;
 }

 public static PVector random2D() {
 Random rnd = new Random();
 rnd.setSeed(System.currentTimeMillis());
 
 float x = (float)(rnd.nextDouble() * 2 - 1.0);
 float y = (float)(rnd.nextDouble() * 2 - 1.0);
 return new PVector(x, y);
 }
 
 public PVector get() {
 PVector rv = new PVector();
 rv.x = this.x;
 rv.y = this.y;
 return rv;
 }
 
 public void add(PVector p) {
 add(p.x, p.y);
 }

 public void add(float x, float y) {
 this.x += x;
 this.y += y;
 }

 public void sub(PVector p) {
 sub(p.x, p.y);
 }

 public void sub(float x, float y) {
 this.x -= x;
 this.y -= y;
 }

 public void mult(PVector p) {
 mult(p.x, p.y);
 }

 public void mult(float x, float y) {
 this.x *= x;
 this.y *= y;
 }

 public void div(PVector p) {
 div(p.x, p.y);
 }

 public void div(float x, float y) {
 this.x /= x;
 this.y /= y;
 }
 
 public float dist(PVector p) {
 float dx = p.x - this.x;
 float dy = p.y - this.y;
 
 float dd = dx * dx + dy * dy;
 float d = (float) Math.sqrt(dd);
 
 return d;
 }
}


4 :

Code:

//
// VolumeMeterView.java - How to use AudioRecord class...
//
// GitHub:
//     https://github.com/yoggy/VolumeMeter
//
// license:
//     Copyright (c) 2017 yoggy <yoggy0@gmail.com>
//     Released under the MIT license
//     http://opensource.org/licenses/mit-license.php;
//
package com.yotamarker.vumeter3;

import android.content.Context;


public class VolumeMeterView extends PseudoP5View {

    float volume_level = 0.0f;

    public VolumeMeterView(Context context) {
        super(context);
    }

    @Override
    protected void setup() {
        size(360, 640);
        frameRate(30);
    }

    @Override
    protected void draw() {
        background(0, 0, 0);

        noStroke();
        fill(0, 255, 0);

        rect(100, (height * (1.0f - volume_level)), width-200, height * volume_level);

        fill(255, 0, 0);
        ellipse(30, 30, 20, 20);
    }

    public void setVolumeLevel(float val) {
        this.volume_level = val;

        // clipping
        if (volume_level < 0.0f) volume_level = 0.0f;
        if (volume_level > 1.0f) volume_level = 1.0f;
    }
}



5 MainActivity.java :

Code:

package com.yotamarker.vumeter3;

import android.Manifest;
import android.content.pm.PackageManager;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.Build;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity {
    public final int PERMISSIONS_REQUEST_CODE_RECORD_AUDIO = 123;
    TextView tv1;
    VolumeMeterView view;

    AudioRecord rec;
    Thread thread;
    boolean break_flag;
    short[] rec_buf;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //requestWindowFeature(Window.FEATURE_NO_TITLE);
        //getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        super.onCreate(savedInstanceState);

        view = new VolumeMeterView(this);

        setContentView(R.layout.activity_main);
        tv1 = findViewById(R.id.txt1);
        view.setup(); // don't forget to call setup()!

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED){
                requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, 0);
                return;
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        if (requestCode == PERMISSIONS_REQUEST_CODE_RECORD_AUDIO) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                startRecording();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        view.onResume(); // don't forget to call onResume()!
        hideSystemUI();

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
                startRecording();
            }
        }
    }

    @Override
    protected void onPause() {
        view.onPause(); // don't forget to call onPause()!
        super.onPause();
        stopRecording();
    }

    // immersive fullscreen mode
    private void hideSystemUI() {
        View decor = this.getWindow().getDecorView();
        decor.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
    }

    void startRecording() {
        int buf_size = AudioRecord.getMinBufferSize(
                44100,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT);

        rec_buf = new short[buf_size];

        rec = new AudioRecord(
                MediaRecorder.AudioSource.DEFAULT,
                44100,
                AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT,
                buf_size);
        rec.startRecording();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                android.os.Process.setThreadPriority(
                        android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

                break_flag = false;
                while(!break_flag) {
                    int size = rec.read(rec_buf, 0, rec_buf.length);
                    if (size <= 0) {
                        return;
                    }

                    int max_val = 0;
                    for (int i = 0; i < size; i += 3) {
                        int val = Math.abs(rec_buf[i]);
                        if (val > max_val) max_val = val;
                    }
                    Log.i("volume",(max_val / (float)Short.MAX_VALUE)+"");
                    ValueStatic.x = (max_val / (float)Short.MAX_VALUE)+"";
                    //tv1.setText((max_val / (float)Short.MAX_VALUE)+"");
                    //Toast.makeText(this,"",Toast.LENGTH_SHORT).show();
                    if (view != null) {
                        view.setVolumeLevel(max_val / (float)Short.MAX_VALUE);
                    }
                }
            }
        });
        t.start();

//        thread = new Thread(this, "VolumeMeter::AudioReadThread");
//        thread.start();
    }

    void stopRecording() {
        if (thread != null) {
            break_flag = true;
            try {
                thread.join();
            } catch (InterruptedException e) {
            }

            rec.stop();
            rec.release();
            rec = null;
        }
    }

    public void test(View view) {

        tv1.setText(ValueStatic.x);

    }

//    @Override
//    public void run() {
//        android.os.Process.setThreadPriority(
//                android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
//
//        break_flag = false;
//        while(!break_flag) {
//            int size = rec.read(rec_buf, 0, rec_buf.length);
//            if (size <= 0) {
//                return;
//            }
//
//            int max_val = 0;
//            for (int i = 0; i < size; i += 3) {
//                int val = Math.abs(rec_buf[i]);
//                if (val > max_val) max_val = val;
//            }
//
//            if (view != null) {
//                view.setVolumeLevel(max_val / (float)Short.MAX_VALUE);
//            }
//        }
//    }
}


permission :
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:id="@+id/txt1"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/btn1"
        android:onClick="test"/>

</android.support.constraint.ConstraintLayout>


POJO static java class :

Code:

package com.yotamarker.vumeter3;

public class ValueStatic {
    public static String x;
}


key notes
toggle change setContentView(view); to setContentView(R.layout.activity_main);
to see the tv1 TextView.and get the volume val in it or see an actual volume meter

the volume value is at : max_val / (float)Short.MAX_VALUE)+""

you can also toggle this lines :
//requestWindowFeature(Window.FEATURE_NO_TITLE);
//getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

 🐉

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio facric.io crashlytics step by step walkthrough

more_horiz
android mobile app development grimoire - Page 4 2jgr3x

facric.io

fabric provides a snitch service called crashlytics. it snitches if users of
your app have errors, with additional hardware info

at fabric.io :
click get fabric, sign up
log in, choose android

open android studio, create a new project, empty activity
in the android studio tool bar : file, settings, plugins, type fabric, click
search in repositories.
click install, click on restart android studio.

now you should see a blue square icon on the tool strip near the rebuild hammer
else on tool bar: view, toolbar. click said square (fabric.io logo).

click the fabric power btn. choose your organization name (from when you registered to the fabric.io)

choose crashlytics, install, apply.

now you should see crashes in the fabric site in the dashboard :greatscott:

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio set volume output level walkthrough

more_horiz
android mobile app development grimoire - Page 4 2jgxuz

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    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/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    android:orientation="vertical"
    android:background="#d0e9ec"
    >
    <TextView
        android:id="@+id/tv_stats"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textSize="25sp"
        />
    <Button
        android:id="@+id/btn_media"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Set Media Volume"
        />
</LinearLayout>


MainActivity :

Code:

package com.yotamarker.volumetweak;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.Random;


public class MainActivity extends AppCompatActivity {
    private Context mContext;
    private Activity mActivity;

    private LinearLayout mRootLayout;
    private Button mBtnSetMediaVolume;
    private TextView mTVStats;

    private AudioManager mAudioManager;
    private Random mRandom = new Random();

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

        // Get the application context
        mContext = getApplicationContext();
        mActivity = MainActivity.this;

        // Get the widget reference from xml layout
        mRootLayout = findViewById(R.id.root_layout);
        mBtnSetMediaVolume = findViewById(R.id.btn_media);
        mTVStats = findViewById(R.id.tv_stats);

        /*
            AudioManager
                AudioManager provides access to volume and ringer mode control.

                Instances of this class must be obtained using
                Context.getSystemService(Class) with the argument AudioManager.class or
                Context.getSystemService(String) with the argument Context.AUDIO_SERVICE.
        */

        // Get the audio manager instance
        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

        // Set click listener for media button
        mBtnSetMediaVolume.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /*
                    STREAM_MUSIC
                        Used to identify the volume of audio streams for music playback
                */

                /*
                    int getStreamVolume (int streamType)
                        Returns the current volume index for a particular stream.

                    Parameters
                        streamType int : The stream type whose volume index is returned.

                    Returns
                        int : The current volume index for the stream.
                */
                int media_current_volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);

                /*
                    int getStreamMaxVolume (int streamType)
                        Returns the maximum volume index for a particular stream.

                    Parameters
                        streamType int : The stream type whose maximum volume index is returned.

                    Returns
                        int : The maximum valid volume index for the stream.
                */
                int media_max_volume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);

                // Get a random number between a specified range
                int random_volume = mRandom.nextInt(((media_max_volume - 0) + 1) + 0);

                /*
                    void setStreamVolume (int streamType, int index, int flags)
                        Sets the volume index for a particular stream.

                        This method has no effect if the device implements a fixed volume policy
                        as indicated by isVolumeFixed().

                        From N onward, volume adjustments that would toggle Do Not Disturb are not
                        allowed unless the app has been granted Do Not Disturb Access.
                        See isNotificationPolicyAccessGranted().

                    Parameters
                        streamType int : The stream whose volume index should be set.
                        index int : The volume index to set. See getStreamMaxVolume(int) for the largest valid value.


                        flags int : One or more flags.
                */
                /*
                    int FLAG_SHOW_UI
                        Show a toast containing the current volume.
                */
                // Set media volume level
                mAudioManager.setStreamVolume(
                        AudioManager.STREAM_MUSIC, // Stream type
                        random_volume, // Index
                        AudioManager.FLAG_SHOW_UI // Flags
                );

                // Display the media volume info on text view
                mTVStats.setText("Media Current Volume : " + media_current_volume);
                mTVStats.append("\nMedia Max Volume : " + media_max_volume);
                mTVStats.append("\nMedia New Volume : " + random_volume);
            }
        });
    }
}

voluken :nice:

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio gesture onTouch walkthrough

more_horiz
android mobile app development grimoire - Page 4 2jj7v6

gets the x y coordinates of where on the view (linear layout in the following example)
is being touched, and displays it on the txt1 TextView + summons a toast
message ("test") when touched.

activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ll1">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/txt1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

</android.support.constraint.ConstraintLayout>


MainActivity.java :

Code:

package com.yotamarker.gesture1;

import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    LinearLayout linearLayout1;
    TextView txt1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        linearLayout1 = findViewById(R.id.ll1);
        txt1 = findViewById(R.id.txt1);
        linearLayout1.setOnTouchListener(new ConstraintLayout.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
// Perform tasks here
                Toast.makeText(v.getContext(),"test",Toast.LENGTH_SHORT).show();
                int x = (int) event.getX();
                int y = (int) event.getY();

                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        Log.i("TAG", "touched down");
                        txt1.setText("touched down");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        Log.i("TAG", "moving: (" + x + ", " + y + ")");
                        txt1.setText("moving: (" + x + ", " + y + ")");
                        break;
                    case MotionEvent.ACTION_UP:
                        Log.i("TAG", "touched up");
                        txt1.setText("touched up");
                        break;
                }


                return true;
            }
        });
    }

    }


hadouken

android mobile app development grimoire - Page 4 2jj8x3


the next example is with 2 touches at the same time :

xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/ll1">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/txt1"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:id="@+id/txt2"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</LinearLayout>

</android.support.constraint.ConstraintLayout>


main java :

Code:

package com.yotamarker.gesture1;

import android.support.constraint.ConstraintLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Layout;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    LinearLayout linearLayout1;
    TextView txt1;
    TextView txt2;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        linearLayout1 = findViewById(R.id.ll1);
        txt1 = findViewById(R.id.txt1);
        txt2 = findViewById(R.id.txt2);
        linearLayout1.setOnTouchListener(new ConstraintLayout.OnTouchListener() {
            public boolean onTouch(View v, MotionEvent event) {
// Perform tasks here
                handleTouch(event);
                return true;
            }
        });
    }
    void handleTouch(MotionEvent m)
    {
        int pointerCount = m.getPointerCount();
        for (int i = 0; i < pointerCount; i++)
        {
            int x = (int) m.getX(i);
            int y = (int) m.getY(i);int id = m.getPointerId(i);
            int action = m.getActionMasked();
            int actionIndex = m.getActionIndex();
            String actionString;
            switch (action)
            {
                case MotionEvent.ACTION_DOWN:
                    actionString = "DOWN"
                    ;
                    break;
                case MotionEvent.ACTION_UP:
                    actionString = "UP";
                    break;
                case MotionEvent.ACTION_POINTER_DOWN:
                    actionString = "PNTR DOWN";
                    break;
                case MotionEvent.ACTION_POINTER_UP:
                    actionString = "PNTR UP";
                    break;
                case MotionEvent.ACTION_MOVE:
                    actionString = "MOVE";
                    break;
                default:
                    actionString = "";
            }
            String touchStatus = "Action: " + actionString + " Index: " +actionIndex + " ID: " + id + " X: " + x + " Y: " + y;
            if (id == 0)
                txt1.setText(touchStatus);
            else
                txt2.setText(touchStatus);
        }
    }}


shouryuuuuken

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio publish APK to play store

more_horiz
android mobile app development grimoire - Page 4 2jpgf2

https://www.raywenderlich.com/1231-android-app-distribution-tutorial-from-zero-to-google-play-store

Build\Generate Signed APK
select modules
start by selecting Create new

Choose a filename and location on your system, set and confirm a secure password,
and fill in the rest of the information about yourself:

Click OK, and Android Studio will create your key store.
You’ll need that file, with its password info, to make any updates to your app, so don’t lose it!

Choose a destination folder for your signed APK, specify your Build Type as release, and click Finish.

With your APK in hand, it’s time to head to the store :

assuming you have a  Google Account :

go to https://play.google.com/apps/publish/signup/
sacrifice $25 of your life points.

With your developer account now registered, your developer console has more options.
Click Publish an Android App on Google Play to continue.

Type in your app name and choose Upload APK
click Upload your first APK to Production, upload your APK

Notice that the check mark next to APK is green, indicating that your APK is ready!
complete filling the other check marks and their respective fields

set payment methode (for your payed apps) :

https://pay.google.com/payments/u/0/home#paymentMethods

check for payment activities :

https://pay.google.com/payments/u/0/home#


:grimoire:

Last edited by Moti Barski on Sat Nov 10, 2018 7:41 pm; edited 2 times in total

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio barcode and QR code scanner walkthrough

more_horiz
android mobile app development grimoire - Page 4 2jtuc6


gragle(module) dependencies :

Code:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    // imported due to conflicts between implementation versions
    implementation "com.android.support:animated-vector-drawable:27.1.1"
    implementation "com.android.support:support-media-compat:27.1.1"
    implementation "com.android.support:support-v4:27.1.1"

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    // barcode scanning imports
    implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
    implementation 'com.tapadoo.android:alerter:2.0.1'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


manifest permissions :

<uses-permission android:name="android.permission.CAMERA" />
   <uses-permission android:name="android.permission.INTERNET" />

res\value\colors.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#008577</color>
    <color name="colorPrimaryDark">#00574B</color>
    <color name="colorAccent">#D81B60</color>
    <color name="colorAccentSecondary">#ad1a7f</color>
</resources>


res\drawable\bg_gradient.xml

Code:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <gradient
        android:angle="135"
        android:centerColor="@color/colorAccentSecondary"
        android:endColor="@color/colorPrimary"
        android:startColor="@color/colorAccent"
        android:type="linear" />

    <corners android:radius="0dp" />
</shape>


activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/bg_gradient"
    tools:context=".MainActivity">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:orientation="vertical"
        android:paddingLeft="40dp"
        android:paddingRight="40dp">

        <TextView
            android:id="@+id/text_view_result"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:fontFamily="sans-serif-light"
            android:gravity="center_horizontal"
            android:text="Scan the QR code to see Result"
            android:textColor="@android:color/white"
            android:textSize="16sp" />

        <Button
            android:id="@+id/btn_copy"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@android:color/transparent"
            android:fontFamily="sans-serif-medium"
            android:foreground="?attr/selectableItemBackground"
            android:gravity="center_horizontal"
            android:paddingTop="60dp"
            android:text="Copy Result"
            android:textColor="@android:color/white"
            android:textSize="18sp" />
    </LinearLayout>

    <Button
        android:id="@+id/btn_scan"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:background="@android:color/transparent"
        android:fontFamily="sans-serif-medium"
        android:foreground="?attr/selectableItemBackground"
        android:paddingBottom="60dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:text="Scan QR Code"
        android:textColor="@android:color/white"
        android:textSize="18sp" />


</RelativeLayout>


MainActivity.java :

Code:

package com.yotamarker.barcode9;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.tapadoo.alerter.Alerter;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_ID_MULTIPLE_PERMISSIONS = 1;
    private Button copy;
    private TextView result;

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

        copy = findViewById(R.id.btn_copy);
        result = findViewById(R.id.text_view_result);

        findViewById(R.id.btn_scan).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (checkAndRequestPermissions()) {
                    new IntentIntegrator(MainActivity.this).initiateScan();
                }
            }
        });

        copy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                android.content.ClipboardManager clipboard = (android.content.ClipboardManager) MainActivity.this.getSystemService(Context.CLIPBOARD_SERVICE);
                android.content.ClipData clip = android.content.ClipData.newPlainText(getString(R.string.app_name), result.getText().toString());
                if (clipboard != null) {
                    clipboard.setPrimaryClip(clip);
                    Toast.makeText(MainActivity.this, "Copied to clipboard", Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, "failed to copy result", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

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

        if (result.getText().toString().trim().equalsIgnoreCase("Scan the QR code to see Result")) {
            copy.setVisibility(View.GONE);
        } else {
            copy.setVisibility(View.VISIBLE);
        }
    }


    private void transparentToolbar() {
        if (Build.VERSION.SDK_INT >= 19 && Build.VERSION.SDK_INT < 21) {
            setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, true);
        }
        if (Build.VERSION.SDK_INT >= 19) {
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
        }
        if (Build.VERSION.SDK_INT >= 21) {
            setWindowFlag(this, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, false);
            getWindow().setStatusBarColor(Color.TRANSPARENT);
        }
    }

    private void setWindowFlag(Activity activity, final int bits, boolean on) {
        Window win = activity.getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        //retrieve scan result
        IntentResult scanningResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
        if (scanningResult != null) {
            //we have a result
            String scanContent = scanningResult.getContents();
            // process received data
            if (scanContent != null && !scanContent.isEmpty()) {
                ((TextView) findViewById(R.id.text_view_result)).setText(scanningResult.getContents());
            } else {
                Alerter.create(MainActivity.this)
                        .setTitle("QR & Barcode Scanner")
                        .setText("Scan Cancelled")
                        .setBackgroundColorRes(R.color.colorPrimaryDark)
                        .show();
            }
        } else {
            Alerter.create(MainActivity.this)
                    .setTitle("QR & Barcode Scanner")
                    .setText("No scan data received!")
                    .setBackgroundColorRes(R.color.colorPrimaryDark)
                    .show();
        }
    }

    private boolean checkAndRequestPermissions() {
        int camera = ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA);
        List<String> listPermissionsNeeded = new ArrayList<>();

        if (camera != PackageManager.PERMISSION_GRANTED) {
            listPermissionsNeeded.add(android.Manifest.permission.CAMERA);
        }
        if (!listPermissionsNeeded.isEmpty()) {
            ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), REQUEST_ID_MULTIPLE_PERMISSIONS);
            return false;
        }
        return true;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_ID_MULTIPLE_PERMISSIONS: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    new IntentIntegrator(MainActivity.this).initiateScan();
                }
            }
        }
    }


}



notes :


// imported due to conflicts between implementation versions
   implementation "com.android.support:animated-vector-drawable:27.1.1"
   implementation "com.android.support:support-media-compat:27.1.1"
   implementation "com.android.support:support-v4:27.1.1"

copy err  at implementation 'com.android.support:appcompat-v7:27.1.1'
search them and paste fix implementations, then :
match ver # of fixes to 27.1.1 (as err causer)


implementation 'com.android.support.constraint:constraint-layout:1.1.3'
is a standart for new apps


unrelated : on example projects DLed from GitHub you can ignore example in the
name classes they are only used for testing

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio record playback audio walkthrough

more_horiz
android mobile app development grimoire - Page 4 2k2c26

res/string.xml :

Code:

<resources>
    <string name="app_name">AudioApp</string>
    <string name="play">Play</string>
    <string name="record">Record</string>
</resources>


activity_main.xml :

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ebookfrenzy.audioapp.AudioAppActivity"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="81dp">

    <Button
        android:id="@+id/playButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="playAudio"
        android:text="@string/play"
        app:layout_constraintBottom_toTopOf="@+id/recordButton"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteY="112dp" />

    <Button
        android:id="@+id/recordButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="recordAudio"
        android:text="@string/record"
        app:layout_constraintBottom_toTopOf="@+id/stopButton"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/playButton" />

    <Button
        android:id="@+id/stopButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="stopAudio"
        android:text="Stop"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/recordButton"
        tools:layout_editor_absoluteY="340dp" />

</android.support.constraint.ConstraintLayout>


AudioAppActivity.java :

Code:

package com.yotamarker.audio;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.pm.PackageManager;
import java.io.IOException;
import android.media.MediaRecorder;
import android.os.Environment;
import android.widget.Button;
import android.view.View;
import android.media.MediaPlayer;
import android.widget.Toast;
import android.support.v4.content.ContextCompat;
import android.Manifest;
import android.support.v4.app.ActivityCompat;

public class AudioAppActivity extends AppCompatActivity {

    private static final int RECORD_REQUEST_CODE = 101;
    private static final int STORAGE_REQUEST_CODE = 102;

    private static MediaRecorder mediaRecorder;
    private static MediaPlayer mediaPlayer;

    private static String audioFilePath;
    private static Button stopButton;
    private static Button playButton;
    private static Button recordButton;

    private boolean isRecording = false;

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

        audioSetup();
    }

    protected boolean hasMicrophone() {
        PackageManager pmanager = this.getPackageManager();
        return pmanager.hasSystemFeature(
                PackageManager.FEATURE_MICROPHONE);
    }

    private void audioSetup()
    {
        recordButton =
                (Button) findViewById(R.id.recordButton);
        playButton = (Button) findViewById(R.id.playButton);
        stopButton = (Button) findViewById(R.id.stopButton);

        if (!hasMicrophone())
        {
            stopButton.setEnabled(false);
            playButton.setEnabled(false);
            recordButton.setEnabled(false);
        } else {
            playButton.setEnabled(false);
            stopButton.setEnabled(false);
        }

        audioFilePath =
                Environment.getExternalStorageDirectory()
                        .getAbsolutePath()
                        + "/myaudio.3gp";

        requestPermission(Manifest.permission.RECORD_AUDIO,
                RECORD_REQUEST_CODE);

    }

    public void recordAudio (View view) throws IOException
    {
        isRecording = true;
        stopButton.setEnabled(true);
        playButton.setEnabled(false);
        recordButton.setEnabled(false);

        try {
            mediaRecorder = new MediaRecorder();
            mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mediaRecorder.setOutputFormat(
                    MediaRecorder.OutputFormat.THREE_GPP);
            mediaRecorder.setOutputFile(audioFilePath);
            mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mediaRecorder.prepare();
        } catch (Exception e) {
            e.printStackTrace();
        }

        mediaRecorder.start();
    }

    public void stopAudio (View view)
    {

        stopButton.setEnabled(false);
        playButton.setEnabled(true);

        if (isRecording)
        {
            recordButton.setEnabled(false);
            mediaRecorder.stop();
            mediaRecorder.release();
            mediaRecorder = null;
            isRecording = false;
        } else {
            mediaPlayer.release();
            mediaPlayer = null;
            recordButton.setEnabled(true);
        }
    }

    public void playAudio (View view) throws IOException
    {
        playButton.setEnabled(false);
        recordButton.setEnabled(false);
        stopButton.setEnabled(true);

        mediaPlayer = new MediaPlayer();
        mediaPlayer.setDataSource(audioFilePath);
        mediaPlayer.prepare();
        mediaPlayer.start();
    }

    protected void requestPermission(String permissionType, int requestCode) {
        int permission = ContextCompat.checkSelfPermission(this,
                permissionType);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,
                    new String[]{permissionType}, requestCode
            );
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case RECORD_REQUEST_CODE: {

                if (grantResults.length == 0
                        || grantResults[0] !=
                        PackageManager.PERMISSION_GRANTED) {

                    recordButton.setEnabled(false);

                    Toast.makeText(this,
                            "Record permission required",
                            Toast.LENGTH_LONG).show();
                } else {
                    requestPermission(
                            Manifest.permission.WRITE_EXTERNAL_STORAGE,
                            STORAGE_REQUEST_CODE);
                }
                return;
            }
            case STORAGE_REQUEST_CODE: {

                if (grantResults.length == 0
                        || grantResults[0] !=
                        PackageManager.PERMISSION_GRANTED) {
                    recordButton.setEnabled(false);
                    Toast.makeText(this,
                            "External Storage permission required",
                            Toast.LENGTH_LONG).show();
                }
                return;
            }
        }
    }
}


AndroidManifest.xml :

add permessions :
<uses-permission android:name=
       "android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="android.permission.RECORD_AUDIO" />



and this line  <activity android:name=".AudioAppActivity">
(MainActivity was replaced to AudioAppActivity)

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio lambda expressions walkthrough

more_horiz
android mobile app development grimoire - Page 4 2k3cyo

view onClick event using lambda expres​sion(short style code used to implement interfaces
enabled by JDK lv8):

activity_main.xml (just added a Button):

Code:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hadouken"
        android:id="@+id/btnLambda"/>

</android.support.constraint.ConstraintLayout>


MainActivity.java :

Code:

package com.yotamarker.btnlambda2;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    Button btnLambda;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnLambda = findViewById(R.id.btnLambda);
        btnLambda.setOnClickListener((View v) -> {
            Toast.makeText(this, "hadouken", Toast.LENGTH_SHORT).show();
        }); // hover over this code click the red mark and choose java lv8 to enable lambda expressions
    }
}


note : read the comment in the code above !


more lambda expressions mini grimoire :
Java lambda expressions are commonly used to implement simple event listeners / callbacks
A Java lambda expression is a function which can be created without belonging to any class.
A Java lambda expression can be passed around as if it was an object and executed on demand.

public interface StateChangeListener {

public void onStateChange(State oldState, State newState);

}

old dead java 7 code to implement interface above :

public class StateOwner {

public void addStateListener(StateChangeListener listener) { ... }

}

new lambda alter code :

StateOwner stateOwner = new StateOwner();

stateOwner.addStateListener(
(oldState, newState) -> System.out.println("State changed")
);

The lambda expressions is this part:
(oldState, newState) -> System.out.println("State changed")

The following interface can be implemented with a lambda expression:

Code:

import java.io.IOException;
import java.io.OutputStream;

public interface MyInterface {

    void printIt(String text);

    default public void printUtf8To(String text, OutputStream outputStream){
        try {
            outputStream.write(text.getBytes("UTF-8"));
        } catch (IOException e) {
            throw new RuntimeException("Error writing String as UTF-8 to OutputStream", e);
        }
    }

    static void printItToSystemOut(String text){
        System.out.println(text);
    }
}


Even though this interface contains 3 methods it can be implemented by a lambda expression, because only one of the methods is unimplemented. Here is how the implementation looks:
MyInterface myInterface = (String text) -> {
System.out.print(text);
};

a lambda with zero params :

() -> System.out.println("Zero parameter lambda");

one param :
(param) -> System.out.println("One parameter: " + param);

When a lambda expression takes a single parameter, you can also omit the parentheses, like this:
param -> System.out.println("One parameter: " + param);

Multiple Parameters

(p1, p2) -> System.out.println("Multiple parameters: " + p1 + ", " + p2);

SP params :

(Car car) -> System.out.println("The car is: " + car.getName());

Returning a Value From a Lambda Expression

var = (param) -> {
System.out.println("param: " + param);
return "return value";
}

In case all your lambda expression is doing is to calculate a return value

(a1, a2) -> { return a1 > a2; }
or
(a1, a2) -> a1 > a2;

Lambdas as Objects

pt1 :
public interface MyComparator {

public boolean compare(int a1, int a2);

}

pt2
MyComparator myComparator = (a1, a2) -> return a1 > a2;

boolean result = myComparator.compare(2, 5);

Local Variable Capture

public interface MyFactory {
public String create(char[] chars);
}

lambda expression that implements the MyFactory interface:

MyFactory myFactory = (chars) -> {
return new String(chars);
};

Right now this lambda expression is only referencing the parameter value passed to it (chars). But we can change that. Here is an updated version that references a String variable declared outside the lambda function body:
String myString = "Test";

MyFactory myFactory = (chars) -> {
return myString + ":" + new String(chars);
};
:hisatsu:

descriptionandroid mobile app development grimoire - Page 4 Emptybuild err fix

more_horiz
after the update you might see this err :
Cause: llvm-rs-cc is missing

and your app fails to build.

here is what I did :
Navigate to Home/User/Android/Sdk/build-tools.
Delete all the folders from there.
at the android studio toolbar : Tools,
SDK Manager, SDK tools tab, uncheck it to delet, check its checkbox and click apply to download the latest version of Android SDK build-tools.
:getter:

descriptionandroid mobile app development grimoire - Page 4 Emptyenabling the codota plugin

more_horiz
android mobile app development grimoire - Page 4 2pphr8

source

open android studio
file, settings
Go to Plugins Preferences and search for “Codota”, then click “Install”

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio gyroscope accelometer walkthrough

more_horiz
android mobile app development grimoire - Page 4 2qb3s9



manifest :

Code:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yotamarker.gyro3">
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>




above I added :
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>

add an interface to the package with main.java :

Code:


public interface AccelerometerListener {

    public void onAccelerationChanged(float x, float y, float z);

    public void onShake(float force);
}


add a class named AccelerometerManager to the package with main.javaAccelerometerManager :

Code:


package com.yotamarker.gyro3;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.widget.Toast;

import java.util.List;
public class AccelerometerManager {

    private static Context context = null;
    /**
     * Accuracy configuration
     */
    private static float threshold = 15.0f;
    private static int interval = 200;

    private static Sensor sensor;
    private static SensorManager sensorManager;
    // you could use an OrientationListener array instead
// if you plans to use more than one listener
    private static AccelerometerListener listener;

    /**
     * indicates whether or not Accelerometer Sensor is supported
     */
    private static Boolean supported;
    /**
     * indicates whether or not Accelerometer Sensor is running
     */
    private static boolean running = false;

    /**
     * Returns true if the manager is listening to orientation changes
     */
    public static boolean isListening() {
        return running;
    }

    /**
     * Unregisters listeners
     */
    public static void stopListening() {
        running = false;
        try {
            if (sensorManager != null && sensorEventListener != null) {
                sensorManager.unregisterListener(sensorEventListener);
            }
        } catch (Exception e) {
        }
    }

    /**
     * Returns true if at least one Accelerometer sensor is available
     */
    public static boolean isSupported(Context cntxt) {
        context = cntxt;
        if (supported == null) {
            if (context != null) {

                sensorManager = (SensorManager) context.
                        getSystemService(Context.SENSOR_SERVICE);

// Get all sensors in device
                List<Sensor> sensors = sensorManager.getSensorList(
                        Sensor.TYPE_ACCELEROMETER);

                supported = new Boolean(sensors.size() > 0);
            } else {
                supported = Boolean.FALSE;
            }
        }
        return supported;
    }

    /**
     * Configure the listener for shaking
     *
     * @param threshold minimum acceleration variation for considering shaking
     * @param interval minimum interval between to shake events
     */
    public static void configure(int threshold, int interval) {
        AccelerometerManager.threshold = threshold;
        AccelerometerManager.interval = interval;
    }

    /**
     * Registers a listener and start listening
     *
     * @param accelerometerListener callback for accelerometer events
     */
    public static void startListening(AccelerometerListener accelerometerListener) {

        sensorManager = (SensorManager) context.
                getSystemService(Context.SENSOR_SERVICE);

// Take all sensors in device
        List<Sensor> sensors = sensorManager.getSensorList(
                Sensor.TYPE_ACCELEROMETER);

        if (sensors.size() > 0) {

            sensor = sensors.get(0);

// Register Accelerometer Listener
            running = sensorManager.registerListener(
                    sensorEventListener, sensor,
                    SensorManager.SENSOR_DELAY_GAME);

            listener = accelerometerListener;
        }
    }

    /**
     * Configures threshold and interval
     * And registers a listener and start listening
     *
     * @param accelerometerListener callback for accelerometer events
     * @param threshold minimum acceleration variation for considering shaking
     * @param interval minimum interval between to shake events
     */
    public static void startListening(AccelerometerListener accelerometerListener, int threshold, int interval) {
        configure(threshold, interval);
        startListening(accelerometerListener);
    }

    private static SensorEventListener sensorEventListener = new SensorEventListener() {

        private long now = 0;
        private long timeDiff = 0;
        private long lastUpdate = 0;
        private long lastShake = 0;

        private float x = 0;
        private float y = 0;
        private float z = 0;
        private float lastX = 0;
        private float lastY = 0;
        private float lastZ = 0;
        private float force = 0;

        public void onAccuracyChanged(Sensor sensor, int accuracy) {
        }

        public void onSensorChanged(SensorEvent event) {
// use the event timestamp as reference
// so the manager precision won't depends
// on the AccelerometerListener implementation
// processing time
            now = event.timestamp;

            x = event.values[0];
            y = event.values[1];
            z = event.values[2];

// if not interesting in shake events
// just remove the whole if then else block
            if (lastUpdate == 0) {
                lastUpdate = now;
                lastShake = now;
                lastX = x;
                lastY = y;
                lastZ = z;
                Toast.makeText(context, "No Motion detected", Toast.LENGTH_SHORT).show();

            } else {
                timeDiff = now - lastUpdate;

                if (timeDiff > 0) {

                    force = Math.abs(x + y + z - lastX - lastY - lastZ);

                    if (Float.compare(force, threshold) > 0) {

                        if (now - lastShake >= interval) {
// trigger shake event
                            listener.onShake(force);
                        } else {
                            Toast.makeText(context, "No Motion detected",
                                    Toast.LENGTH_SHORT).show();

                        }
                        lastShake = now;
                    }
                    lastX = x;
                    lastY = y;
                    lastZ = z;
                    lastUpdate = now;
                } else {
                    Toast.makeText(context, "No Motion detected", Toast.LENGTH_SHORT).show();
                }
            }
// trigger change event
            listener.onAccelerationChanged(x, y, z);
        }
    };
}


activity_main.xml :

Code:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Main Screen"
        android:textColor="@android:color/black"
        android:textSize="32sp"/>
</LinearLayout>


MainActivity.java :

Code:


package com.yotamarker.gyro3;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements AccelerometerListener {
    TextView tv1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv1 = findViewById(R.id.textView);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (AccelerometerManager.isSupported(this)) {
            AccelerometerManager.startListening(this);
        }
    }

    @Override
    public void onAccelerationChanged(float x, float y, float z) {
        tv1.setText("x: = " + x + " y= " + y + " z = " + z);
    }

    @Override
    public void onShake(float force) {
        Toast.makeText(this, "Motion detected", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onStop() {
        super.onStop();

//Check device supported Accelerometer senssor or not
        if (AccelerometerManager.isListening()) {

//Start Accelerometer Listening
            AccelerometerManager.stopListening();

            Toast.makeText(this, "onStop Accelerometer Stopped", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (AccelerometerManager.isListening()) {
            AccelerometerManager.stopListening();

            Toast.makeText(this, "onDestroy Accelerometer Stopped", Toast.LENGTH_SHORT).show();
        }
    }
}


hadouken

Last edited by Moti Barski on Sat Feb 06, 2021 7:16 pm; edited 1 time in total

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio magnetometer for metal detecting step by step walkthrough

more_horiz
android mobile app development grimoire - Page 4 2qg4ci

activity_main.xml :

Code:


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:background="#000000"
    tools:context="com.yotamarker.magneto1.MainActivity">

    <TextView
        android:id="@+id/value"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="45.00"
        android:textColor="#FFFFFF"
        android:textStyle="bold"
        android:textSize="23sp"
        android:layout_centerInParent="true"/>
</RelativeLayout>


MainActivity.java

Code:


package com.yotamarker.magneto1;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;

public class MainActivity extends AppCompatActivity implements SensorEventListener{

    private TextView value;
    private SensorManager sensorManager;
    public static DecimalFormat DECIMAL_FORMATTER;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        value = (TextView) findViewById(R.id.value);
        // define decimal formatter
        DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.US);
        symbols.setDecimalSeparator('.');
        DECIMAL_FORMATTER = new DecimalFormat("#.000", symbols);

        sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this,
                sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            // get values for each axes X,Y,Z
            float magX = event.values[0];
            float magY = event.values[1];
            float magZ = event.values[2];

            double magnitude = Math.sqrt((magX * magX) + (magY * magY) + (magZ * magZ));

            // set value on the screen
            value.setText(DECIMAL_FORMATTER.format(magnitude) + " \u00B5Tesla");
        }

    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
    }
}


hadouken :interesting:

Last edited by Moti Barski on Sat Feb 06, 2021 7:18 pm; edited 2 times in total

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio compass walkthrough

more_horiz
android mobile app development grimoire - Page 4 Pointer

AndroidManifest.xml, add permissions :

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

activity_main.xml :

Code:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    tools:context="com.yotamarker.compass.MainActivity" >

    <ImageView
        android:id="@+id/pointer"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/pointer" />

</RelativeLayout>


MainActivity.java :

Code:

package com.yotamarker.compass;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

public class MainActivity extends Activity implements SensorEventListener {

    private ImageView mPointer;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;
    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;
    private float[] mR = new float[9];
    private float[] mOrientation = new float[3];
    private float mCurrentDegree = 0f;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        mPointer = (ImageView) findViewById(R.id.pointer);
    }

    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this, mAccelerometer);
        mSensorManager.unregisterListener(this, mMagnetometer);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if (event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if (mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            SensorManager.getOrientation(mR, mOrientation);
            float azimuthInRadians = mOrientation[0];
            float azimuthInDegress = (float)(Math.toDegrees(azimuthInRadians)+360)%360;
            RotateAnimation ra = new RotateAnimation(
                    mCurrentDegree,
                    -azimuthInDegress,
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF,
                    0.5f);

            ra.setDuration(250);

            ra.setFillAfter(true);

            mPointer.startAnimation(ra);
            mCurrentDegree = -azimuthInDegress;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }

}


add an image named pointer.jpg to :
res, drawable folder in the projects solution explorer



Last edited by Moti Barski on Sat Feb 06, 2021 7:19 pm; edited 1 time in total

descriptionandroid mobile app development grimoire - Page 4 Emptyandroid studio instant app walkthrough

more_horiz
android mobile app development grimoire - Page 4 2r7snq

skipable intro :

an instant app is a single feature (such as activity) that does not need an installation
and runs using a url. in other words, you transform the app into a website

base feature module : the main AndroidManifest.xml file is defined here too with all the activities,
permissions etc.
This module would hold all the resources for the application – drawable, mipmap icons etc

In the build.gradle file of this module, we set the plugin to com.android.feature as well as set
baseFeature true inside the android block.

create a free domain at : www.000webhost.com

install the instant Apps development SDK :
tools, SDK manager, SDK tools, the google play instant development SDK entry should be checked


*********************************************************************************************************
open a new project and on the naming screen check : include instant app support.
name the feature myfeature

when the new empty activity creates, type the Instant App URL host (your domain)

tools, app links assistant, open URL Mapping Editor,
set the host URL + set the URL (actual) activity, this will update the manifest.

**********************************************************************************************************
set the default activity url  and upload it:
click select activity, click insert code.
click open digital asset links file generator, paste site domain,
click generate digital asset links file, and save the file it generates(save file btn) to the
link you gave it :
at 000webhost (add contents to your site) :
folder name : .whateva, and upload it there, click (at android studio) link and varify
you may need to reclick link and varify.

compile :
at the toolbar near the compile arrow, drop down choose edit configuration,
and set the host URL. or :
Now to run the application we need to set a default-url in the manifest.
We have two ways to do so:
Set the meta-data tag with the default url in the manifest itself.
Copy

<meta-data android:name="default-url"
       android:value="https://www.company.com/preview" />


you can run the app from the url or debug.


***********************************************************************************************************
add a feature :
Right click on main in featureName/java/com.projectName.com.
Inside the package create an activity by right-clicking and then New | Activity | Settings Activity.


add a URL for the new activity :
Tools | App Links Assistant | Open URL Mapping Editor. Over there add a new url mapper for the new Activity
unless you already added the url when you created the new activity in its wizard.

click select activity (right window the link assistant), click insert code.
click open digital asset links file generator (right window the link assistant), paste site domain,
click generate digital asset links file, and save the file it generates(save file btn) to the
link which looks like : hadouken.com/activityName/json
so you need to add a folder activityName to your domain host and upload the json file to that folder.

from an activity, teleport to another activity(feature) using this code :

Code:



 Intent intent = new Intent(Intent.ACTION_VIEW,
                        Uri.parse("https://company.com/activityName"));
                intent.setPackage(getPackageName());
                intent.addCategory(Intent.CATEGORY_BROWSABLE);
                startActivity(intent);


the above code can be place in a btn click event for example

***********************************************************************************************************
at the google play store :
Once an application is uploaded to the playstore, which url is launched first?
We need to set a default-url in our manifest. On whichever activity it is set, that gets launched first.
Once an application on playstore is instant app compatible, we can launch it using the link:
https://play.google.com/store/apps/details?id={package_name}&launch=true.




:tokushushoukan

Last edited by Moti Barski on Sat Feb 06, 2021 7:20 pm; edited 1 time in total
privacy_tip Permissions in this forum:
You cannot reply to topics in this forum
power_settings_newLogin to reply