Generating SHA-1 for Google API

When you want to interface with any Google API e.g. YouTube from within your Android App, you need to register your app in the developer console.

You have to provide a SHA-1 key which can be generated as following:

Command line

$ chmod u+x gradlew
$ ./gradlew signingReport

Play sound on Android

Resource files shall be placed under app\src\main\res\raw

import android.media.AudioManager
import android.media.SoundPool
import android.os.Build
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() {
    private var mCSoundOne: Int = 0
    private lateinit var mSoundPool: SoundPool
    private var mLoaded = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mSoundPool = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Log.d("SoundPoolTest", "Building Soundpool")
            SoundPool.Builder().setMaxStreams(1).build()
        } else {
            SoundPool(1, AudioManager.STREAM_MUSIC, 1)
        }
        mSoundPool.setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener { soundPool, sampleId, status ->
            Log.d("SoundPoolTest", "Load Completed")
            mLoaded = true
        })
        Log.d("SoundPoolTest", "Loading wav")
        mCSoundOne = mSoundPool.load(applicationContext, R.raw.eins, 1)

    }

    fun play_one(view: View?) {
        Log.d("SoundPoolTest", "Button Clicked")
        if (mLoaded) {
            Log.d("SoundPoolTest", "Playing wav")
            mSoundPool.play(mCSoundOne, 1.0f, 1.0f, 0, 0, 1.0f)
        }
    }
}

Kotlin Scripts with Gradle

If you are using gradle and you want to run a Kotlin script you have to add the following to your build.gradle file

dependencies {
     implementation "org.jetbrains.kotlin:kotlin-stdlib"
     compile group: 'org.jetbrains.kotlin', name: 'kotlin-script-runtime', version: '1.4.32'
}

Sound and music with pygame

pip install pygame

Sound

import pygame

if __name__ == '__main__':
    pygame.mixer.init()
    sound = pygame.mixer.Sound("./sound.wav")
    channel = sound.play()
    while channel.get_busy():
        pygame.time.wait(100)
        print("Playing...")
    print("Finished.")

 

Music

import pygame

if __name__ == '__main__':
    pygame.mixer.init()
    pygame.mixer.music.load("./sound.mp3")
    pygame.mixer.music.play()
    while pygame.mixer.music.get_busy():
        pygame.time.wait(100)  # ms
        print("Playing...")
    print("Finished.")

Getting Location Info in Android

Manifest

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

Activity

 

public static final int REQUEST_CODE = 123;
LocationManager mLocationManager; 
LocationListener mLocationListener;
@Override
protected void onResume(){
    super.onResume();
    getCurrentLocation();
}
private void getCurrentLocation() {
    Log.d("Clima", "getWeatherForCurrentLocation");
    mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    mLocationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            Log.d("Clima", "onLocationChanged");
            String longitude = String.valueOf(location.getLongitude());
            String latitude = String.valueOf(location.getLatitude());
            Log.d("Clima", "longitude is: " +longitude);
            Log.d("Clima","latitude is: " + latitude);
        }

        @Override
        public void onStatusChanged(String s, int i, Bundle bundle) {

        }

        @Override
        public void onProviderEnabled(String s) {

        }

        @Override
        public void onProviderDisabled(String s) {

        }
    };
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
            && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE);
        return;
    }
    mLocationManager.requestLocationUpdates(LOCAION_PROVIDER, MIN_TIME, MIN_DISTANCE, mLocationListener);
}

 

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.d("Clima", "onRequestPermissionsResult");
    if (requestCode == REQUEST_CODE) {
        if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            getCurrentLocation();
        }
    }
}

Passing data between AndroidActivities

Sending data

private void openVideoActivity(String video) {
    Intent newActivity = new Intent(this, PlayerActivity.class);
    newActivity.putExtra("videoId", video);
    startActivity(newActivity);
}

Retrieving data

final String videoID = getIntent().getExtras().getString("videoID");

In Kotlin it looks like this:

val intent = Intent(this, NewActivity::class.java).apply {
    putExtra("EXTRA_MESSAGE", "Test 123")
}
startActivity(intent)

Retrieving

val message = intent.getStringExtra("EXTRA_MESSAGE")

Python variable length arguments

def print_person_varargs(name, *vargs):
    print(name)
    print(vargs)
    for arg in vargs:
        print(arg)


def print_person_kwargs(name, **kwargs):
    print(name)
    print(kwargs)
    for i, j in kwargs.items():
        print(i, j)


print_person_varargs("Jörn", 38, "Emskirchen")
print_person_kwargs("Jörn", age=38, city="Emskirchen")

Android Services

Service Manager

$ adb shell service list
shell@g3:/ $ service list
Found 132 services:
0 AtCmdFwd: [com.qualcomm.atfwd.IAtCmdFwd]
1 lge.apdu: [com.lge.smartcard.internal.apdu.uicc.IUiccAccess]
2 telecom: [com.android.internal.telecom.ITelecomService]
3 phone: [com.android.internal.telephony.ITelephony]

Android Spinner

Spinner spinner = findViewById(R.id.currency_spinner);

// Create an ArrayAdapter using the String array and a spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
        R.array.spinner_values, R.layout.spinner_item);

// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);

// Apply the adapter to the spinner
spinner.setAdapter(adapter);


spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        Log.d("Spinner Demo", "" + parent.getItemAtPosition(position));
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
        Log.d("Spinner Demo", "Nothing selected");
    }
});

Switch between activities

public class MainActivity extends AppCompatActivity {
    private Button mAddButton;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mAddButton = findViewById(R.id.addButton);
        mAddButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openAddActivity();
            } 
        });
}

    public void openAddActivity(){
       Intent intent = new Intent(this, Main2Activity.class);
       startActivity(intent);
}