Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
patri9ck committed Nov 5, 2021
0 parents commit 06a6774
Show file tree
Hide file tree
Showing 46 changed files with 1,529 additions and 0 deletions.
26 changes: 26 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
plugins {
id 'com.android.application'
}

android {
compileSdk 31

defaultConfig {
applicationId "dev.patri9ck.a2ln"
minSdk 24
targetSdk 31
versionCode 1
versionName "1.0"
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

dependencies {
implementation 'com.google.code.gson:gson:2.8.9'
implementation 'com.google.android.material:material:1.4.0'
implementation 'org.zeromq:jeromq:0.5.2'
}
34 changes: 34 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.patri9ck.a2ln">

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_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/Theme">
<activity
android:name="dev.patri9ck.a2ln.address.AddressesActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="dev.patri9ck.a2ln.app.AppsActivity" />

<service
android:name="dev.patri9ck.a2ln.notification.NotificationReceiver"
android:exported="false"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
</application>
</manifest>
Binary file added app/src/main/ic_launcher-playstore.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions app/src/main/java/dev/patri9ck/a2ln/address/Address.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package dev.patri9ck.a2ln.address;

public class Address {

private String host;
private int port;

public Address() {}

public Address(String host, int port) {
this.host = host;
this.port = port;
}

public String getHost() {
return host;
}

public int getPort() {
return port;
}

@Override
public String toString() {
return host + ":" + port;
}
}
144 changes: 144 additions & 0 deletions app/src/main/java/dev/patri9ck/a2ln/address/AddressesActivity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package dev.patri9ck.a2ln.address;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.view.View;
import android.widget.EditText;

import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.google.gson.Gson;

import java.util.List;

import dev.patri9ck.a2ln.R;
import dev.patri9ck.a2ln.app.AppsActivity;
import dev.patri9ck.a2ln.configuration.Configuration;
import dev.patri9ck.a2ln.configuration.Storage;
import dev.patri9ck.a2ln.notification.NotificationReceiver;

public class AddressesActivity extends Activity {

private Gson gson = new Gson();

private Storage storage;
private Configuration configuration;

private List<Address> addresses;
private AddressesAdapter addressesAdapter;

private NotificationReceiver notificationReceiver;
private boolean bound;

private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
notificationReceiver = ((NotificationReceiver.NotificationReceiverBinder) service).getNotificationReceiver();

notificationReceiver.setAddresses(addresses);
}

@Override
public void onServiceDisconnected(ComponentName name) {
notificationReceiver = null;
}
};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.addresses_activity);

storage = new Storage(this);
configuration = gson.fromJson(getIntent().getStringExtra(Configuration.class.getName()), Configuration.class);

if (configuration == null) {
configuration = storage.loadConfiguration();
}

loadAddressesRecyclerView();
}

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

bound = bindService(new Intent(this, NotificationReceiver.class), serviceConnection, 0);
}

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

if (!bound) {
return;
}

unbindService(serviceConnection);
bound = false;
}

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

storage.saveConfiguration(configuration);
}

public void onAdd(View view) {
String host = ((EditText) findViewById(R.id.host_edit_text)).getText().toString();
String port = ((EditText) findViewById(R.id.port_edit_text)).getText().toString();

if (host.isEmpty() || port.isEmpty()) {
return;
}

for (Address address : addresses) {
if (address.getHost().equals(host)) {
return;
}
}

addresses.add(new Address(host, Integer.parseInt(port)));

addressesAdapter.notifyItemInserted(addresses.size());

if (notificationReceiver == null) {
return;
}

notificationReceiver.setAddresses(addresses);
}

public void onApps(View view) {
Intent intent = new Intent(this, AppsActivity.class);

intent.putExtra(Configuration.class.getName(), gson.toJson(configuration));

startActivity(intent);
}

public void onPermission(View view) {
startActivity(new Intent(Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS));
}

private void loadAddressesRecyclerView() {
addresses = configuration.getAddresses();
addressesAdapter = new AddressesAdapter(addresses);

RecyclerView addressesRecyclerView = findViewById(R.id.addresses_recycler_view);

addressesRecyclerView.setAdapter(addressesAdapter);
addressesRecyclerView.setLayoutManager(new LinearLayoutManager(this));

new ItemTouchHelper(new SwipeToDeleteCallback(this, addresses, addressesAdapter)).attachToRecyclerView(addressesRecyclerView);
}
}
47 changes: 47 additions & 0 deletions app/src/main/java/dev/patri9ck/a2ln/address/AddressesAdapter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package dev.patri9ck.a2ln.address;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

import java.util.List;

import dev.patri9ck.a2ln.R;

public class AddressesAdapter extends RecyclerView.Adapter<AddressesAdapter.AddressViewHolder> {

private List<Address> addresses;

public AddressesAdapter(List<Address> addresses) {
this.addresses = addresses;
}

@Override
public AddressViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new AddressViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.address_item, parent, false));
}

@Override
public void onBindViewHolder(AddressViewHolder holder, int position) {
holder.addressTextView.setText(addresses.get(position).toString());
}

@Override
public int getItemCount() {
return addresses.size();
}

protected static class AddressViewHolder extends RecyclerView.ViewHolder {

private final TextView addressTextView;

public AddressViewHolder(View itemView) {
super(itemView);

addressTextView = itemView.findViewById(R.id.address_text_view);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package dev.patri9ck.a2ln.address;

import androidx.recyclerview.widget.ItemTouchHelper;
import androidx.recyclerview.widget.RecyclerView;

import com.google.android.material.snackbar.Snackbar;

import java.util.List;

import dev.patri9ck.a2ln.R;

public class SwipeToDeleteCallback extends ItemTouchHelper.SimpleCallback {

private AddressesActivity addressesActivity;
private List<Address> addresses;
private AddressesAdapter addressesAdapter;

public SwipeToDeleteCallback(AddressesActivity addressesActivity, List<Address> addresses, AddressesAdapter addressesAdapter) {
super(0, ItemTouchHelper.LEFT);

this.addressesActivity = addressesActivity;
this.addresses = addresses;
this.addressesAdapter = addressesAdapter;
}

@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
return false;
}

@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
int position = viewHolder.getAdapterPosition();

Address address = addresses.remove(position);

addressesAdapter.notifyItemRemoved(position);

Snackbar.make(addressesActivity.findViewById(android.R.id.content), R.string.removed_address, Snackbar.LENGTH_LONG)
.setAction(R.string.removed_address_undo, v -> {
addresses.add(position, address);

addressesAdapter.notifyItemInserted(position);
}).show();
}
}
38 changes: 38 additions & 0 deletions app/src/main/java/dev/patri9ck/a2ln/app/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package dev.patri9ck.a2ln.app;

import android.graphics.drawable.Drawable;

public class App {

private String name;
private String packageName;
private Drawable icon;
private boolean enabled;

public App(String name, String packageName, Drawable icon, boolean enabled) {
this.name = name;
this.packageName = packageName;
this.icon = icon;
this.enabled = enabled;
}

public String getName() {
return name;
}

public String getPackageName() {
return packageName;
}

public Drawable getIcon() {
return icon;
}

public boolean isEnabled() {
return enabled;
}

public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
}
Loading

0 comments on commit 06a6774

Please sign in to comment.