Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
c0742cef5d | |||
6f4320b074 | |||
000f2ee655 | |||
be020bdfcd | |||
6be6081f27 | |||
303eed4e3f | |||
f7f28ea807 | |||
75a4874225 | |||
989299cf31 |
2
.idea/misc.xml
generated
2
.idea/misc.xml
generated
@ -3,8 +3,10 @@
|
||||
<component name="DesignSurface">
|
||||
<option name="filePathToZoomLevelMap">
|
||||
<map>
|
||||
<entry key="../../../../layout/custom_preview.xml" value="0.3" />
|
||||
<entry key="app/src/main/res/drawable-v24/ic_launcher_foreground.xml" value="0.2595" />
|
||||
<entry key="app/src/main/res/layout/activity_main.xml" value="0.33605072463768115" />
|
||||
<entry key="app/src/main/res/layout/activity_scan.xml" value="0.271875" />
|
||||
<entry key="app/src/main/res/layout/activity_start.xml" value="0.33605072463768115" />
|
||||
</map>
|
||||
</option>
|
||||
|
@ -1,7 +1,8 @@
|
||||
# Bookwyrm-android
|
||||
A crappy attempt at creating an Android application for Bookwyrm. Basically, it is just bookwyrm put into a 'webview' element.
|
||||
An Android application for Bookwyrm. Basically, it is just bookwyrm put into a 'webview' element.
|
||||
What it does? It enables you to use BookWyrm on your Android phone without having to use a browser to go to it every time.
|
||||
It can also open links to userpages of Bookwyrm users.
|
||||
It can also open links to userpages of Bookwyrm users and it can scan ISBN codes.
|
||||
|
||||
This application works on: Android 6 and above.
|
||||
|
||||
And if you want to know, I am `@StoryDragon@wyrms.de` on BookWyrm.
|
||||
|
@ -9,10 +9,10 @@ android {
|
||||
applicationId "nl.privacydragon.bookwyrm"
|
||||
minSdk 23
|
||||
targetSdk 31
|
||||
versionCode 3
|
||||
versionName "1.2.0"
|
||||
versionCode 7
|
||||
versionName "1.3.0"
|
||||
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@ -29,9 +29,14 @@ android {
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||
implementation 'com.android.support.constraint:constraint-layout:2.0.4'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
implementation 'com.google.zxing:core:3.3.0'
|
||||
implementation 'com.journeyapps:zxing-android-embedded:4.3.0@aar'
|
||||
//implementation 'com.github.yuriy-budiyev:code-scanner:2.1.2'
|
||||
|
||||
|
||||
}
|
Binary file not shown.
BIN
app/release/Bookwyrm-v1.3.0.apk
Normal file
BIN
app/release/Bookwyrm-v1.3.0.apk
Normal file
Binary file not shown.
@ -11,8 +11,8 @@
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 3,
|
||||
"versionName": "1.2.0",
|
||||
"versionCode": 7,
|
||||
"versionName": "1.3.0",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
],
|
||||
|
@ -1,8 +1,8 @@
|
||||
package nl.privacydragon.bookwyrm;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.test.InstrumentationRegistry;
|
||||
import android.support.test.runner.AndroidJUnit4;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -4,6 +4,13 @@
|
||||
package="nl.privacydragon.bookwyrm">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
|
||||
<meta-data
|
||||
android:name="android.webkit.WebView.MetricsOptOut"
|
||||
android:value="true" />
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
@ -15,7 +22,6 @@
|
||||
<activity
|
||||
android:name=".HandlerActivity"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
@ -23,9 +29,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="wyrms.de"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -34,9 +40,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="bookwyrm.social"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -45,9 +51,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="book.dansmonorage.blue"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -56,9 +62,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="yyyyy.club"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -67,9 +73,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="books.mxhdr.net"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -78,9 +84,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="ziurkes.group.lt"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -89,9 +95,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="books.solarpunk.moe"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -100,9 +106,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="reading.taks.garden"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -111,9 +117,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="bookwyrm.spaceling.sh"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -122,9 +128,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="lire.boitam.eu"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -133,9 +139,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="kirja.casa"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -144,9 +150,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="books.badwolfbay.games"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -155,9 +161,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="books.unexist.dev"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -166,9 +172,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="bookwyrm.cincodenada.com"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -177,9 +183,9 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="books.underscore.world"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
@ -188,9 +194,53 @@
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="bookwyrm.tardis.pw"
|
||||
android:pathPrefix="/user/" />
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="tankie.ml"
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="masstoc.io"
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="books.mennisch.net"
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="bookwyrm.pt"
|
||||
android:pathPrefix="/user/"
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
|
@ -1,16 +1,41 @@
|
||||
package nl.privacydragon.bookwyrm;
|
||||
|
||||
import static androidx.core.content.ContextCompat.startActivity;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.net.Uri;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
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.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.webkit.ConsoleMessage;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.PermissionRequest;
|
||||
import android.webkit.WebChromeClient;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -31,6 +56,8 @@ import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
public class HandlerActivity extends AppCompatActivity {
|
||||
|
||||
WebView myWebView;
|
||||
ProgressBar LoadIndicator;
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -41,8 +68,20 @@ public class HandlerActivity extends AppCompatActivity {
|
||||
String appLinkAction = appLinkIntent.getAction();
|
||||
Uri appLinkData = appLinkIntent.getData();
|
||||
// End of auto-generated stuff
|
||||
WebView myWebView = (WebView) findViewById(R.id.webview);
|
||||
LoadIndicator = (ProgressBar) findViewById(R.id.progressBar3);
|
||||
myWebView = (WebView) findViewById(R.id.webview);
|
||||
myWebView.getSettings().setJavaScriptEnabled(true);
|
||||
myWebView.getSettings().setDomStorageEnabled(true);
|
||||
myWebView.addJavascriptInterface(new Object()
|
||||
{
|
||||
@JavascriptInterface // For API 17+
|
||||
public void performClick()
|
||||
{
|
||||
ScanBarCode();
|
||||
|
||||
}
|
||||
}, "scan");
|
||||
//myWebView.addJavascriptInterface(new HandlerActivity.WebAppInterface(this), "Android");
|
||||
//The user credentials are stored in the shared preferences, so first they have to be read from there.
|
||||
String defaultValue = "none";
|
||||
SharedPreferences sharedPref = HandlerActivity.this.getSharedPreferences(getString(R.string.server), Context.MODE_PRIVATE);
|
||||
@ -60,10 +99,15 @@ public class HandlerActivity extends AppCompatActivity {
|
||||
String pathMaybe = appLinkData.getPath();
|
||||
String toGoServer = "bla";
|
||||
if (pathMaybe.contains("user")) {
|
||||
//If the path contains 'user', it is a user profile.
|
||||
String notAtUser = pathMaybe.substring(pathMaybe.indexOf("user") + 5); //This line gets the username.
|
||||
String atUser = notAtUser + "@" + appLinkData.getHost(); //This appends @[HOST] to the string, so we have the full username thing needed.
|
||||
toGoServer = "https://" + server + "/user/" + atUser;
|
||||
//If the path contains 'user', it is a user profile, unless it is followed by something like 'review'.
|
||||
if (pathMaybe.contains("review") || pathMaybe.contains("generatednote") || pathMaybe.contains("quotation") || pathMaybe.contains("comment") ) {
|
||||
toGoServer = "https://" + appLinkData.getHost() + pathMaybe;
|
||||
}
|
||||
else {
|
||||
String notAtUser = pathMaybe.substring(pathMaybe.indexOf("user") + 5); //This line gets the username.
|
||||
String atUser = notAtUser + "@" + appLinkData.getHost(); //This appends @[HOST] to the string, so we have the full username thing needed.
|
||||
toGoServer = "https://" + server + "/user/" + atUser;
|
||||
}
|
||||
} else {
|
||||
startActivity(new Intent(HandlerActivity.this, nl.privacydragon.bookwyrm.StartActivity.class));
|
||||
}
|
||||
@ -129,32 +173,150 @@ public class HandlerActivity extends AppCompatActivity {
|
||||
String finalToGoServer = toGoServer;
|
||||
myWebView.setWebViewClient(new HandlerActivity.MyWebViewClient() {
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
LoadIndicator.setVisibility(View.GONE);
|
||||
|
||||
view.loadUrl("javascript:(function() { document.getElementById('id_password').value = '" + passw + "'; ;})()");
|
||||
view.loadUrl("javascript:(function() { document.getElementById('id_localname').value = '" + name + "'; ;})()");
|
||||
view.loadUrl("javascript:(function() { if (window.location.href == '" + finalToGoServer + "') { document.getElementsByName(\"login\")[0].submit();} ;})()");
|
||||
|
||||
view.loadUrl("javascript:(function() { if (window.location.href == '" + finalToGoServer + "' && !/(review|generatednote|quotation|comment)/i.test(window.location.href)) { document.getElementsByName(\"login\")[0].submit();} ;})()");
|
||||
view.loadUrl("javascript:(function() { if (window.location.href == 'https://" + server + "') { document.getElementsByName(\"login\")[0].submit();} ;})()");
|
||||
view.loadUrl("javascript:(function() { if (/(review|generatednote|quotation|comment)/i.test(window.location.href)) { document.getElementsByClassName(\"block\")[0].innerHTML = ` <a href=\"https://"+ server +"\" class=\"button\" data-back=\"\">\n" +
|
||||
" <span class=\"icon icon-arrow-left\" aria-hidden=\"true\"></span>\n" +
|
||||
" <span><b>Back to homeserver</b></span>\n" +
|
||||
" </a>`;} ;})()");
|
||||
view.loadUrl("javascript:(function() { " +
|
||||
"const ISBN = document.createElement(\"p\");" +
|
||||
"ISBN.innerHTML = '<br/>Click to scan ISBN';" +
|
||||
"ISBN.addEventListener('click', () => {" +
|
||||
" scan.performClick();" +
|
||||
"});" +
|
||||
"const NewCenter = document.createElement(\"center\");" +
|
||||
"NewCenter.append(ISBN);" +
|
||||
"nav = document.body;" +
|
||||
"nav.insertBefore(NewCenter, nav.children[0]);" +
|
||||
";})()");
|
||||
}
|
||||
});
|
||||
/*myWebView.setWebChromeClient(new WebChromeClient(){
|
||||
// Need to accept permissions to use the camera
|
||||
@Override
|
||||
public void onPermissionRequest(PermissionRequest request) {
|
||||
String permission = Manifest.permission.CAMERA;
|
||||
int grant = ContextCompat.checkSelfPermission(HandlerActivity.this, permission);
|
||||
if (grant != PackageManager.PERMISSION_GRANTED) {
|
||||
String[] permission_list = new String[1];
|
||||
permission_list[0] = permission;
|
||||
ActivityCompat.requestPermissions(HandlerActivity.this, permission_list, 1);
|
||||
}
|
||||
request.grant(request.getResources());
|
||||
final String[] requestedResources = request.getResources();
|
||||
for (String r : requestedResources) {
|
||||
if (r.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
|
||||
request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});*/
|
||||
//Here, load the login page of the server. That actually does all that is needed.
|
||||
//myWebView.loadUrl("https://serratus.github.io/quaggaJS/examples/live_w_locator.html");
|
||||
myWebView.loadUrl(toGoServer);
|
||||
}
|
||||
|
||||
public void ScanBarCode() {
|
||||
String permission = Manifest.permission.CAMERA;
|
||||
int grant = ContextCompat.checkSelfPermission(HandlerActivity.this, permission);
|
||||
if (grant != PackageManager.PERMISSION_GRANTED) {
|
||||
String[] permission_list = new String[1];
|
||||
permission_list[0] = permission;
|
||||
ActivityCompat.requestPermissions(HandlerActivity.this, permission_list, 1);
|
||||
}
|
||||
|
||||
IntentIntegrator intentIntegrator = new IntentIntegrator(HandlerActivity.this);
|
||||
intentIntegrator.setDesiredBarcodeFormats(intentIntegrator.ALL_CODE_TYPES);
|
||||
intentIntegrator.setBeepEnabled(true);
|
||||
intentIntegrator.setCameraId(0);
|
||||
intentIntegrator.setPrompt("SCAN");
|
||||
intentIntegrator.setBarcodeImageEnabled(false);
|
||||
intentIntegrator.initiateScan();
|
||||
|
||||
//return "blup";
|
||||
//return "bla";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
IntentResult Result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (Result != null) {
|
||||
if (Result.getContents() == null) {
|
||||
Toast.makeText(this, "cancelled", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Log.d("MainActivity", "Scanned");
|
||||
myWebView.loadUrl("Javascript:(function() {document.getElementById('search_input').value = " + Result.getContents() + ";" +
|
||||
"document.getElementsByTagName('form')[0].submit(); ;})()");
|
||||
LoadIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*public class WebAppInterface {
|
||||
Context mContext;
|
||||
|
||||
//Instantiate the interface and set the context
|
||||
WebAppInterface(Context c) {
|
||||
mContext = c;
|
||||
}
|
||||
|
||||
// Show a toast from the web page
|
||||
@JavascriptInterface
|
||||
public void showToast(String toast) {
|
||||
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}*/
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Check if the key event was the Back button and if there's history
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
|
||||
myWebView.goBack();
|
||||
return true;
|
||||
}
|
||||
// If it wasn't the Back key or there's no web page history, bubble up to the default
|
||||
// system behavior (probably exit the activity)
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
//Here is code to make sure that links of the bookwyrm server are handled withing the webview client, instead of having it open in the default browser.
|
||||
//Yes, I used the web for this too.
|
||||
private class MyWebViewClient extends WebViewClient {
|
||||
@Override
|
||||
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
|
||||
// ATTENTION: This was auto-generated to handle app links.
|
||||
Intent appLinkIntent = getIntent();
|
||||
String appLinkAction = appLinkIntent.getAction();
|
||||
Uri appLinkData = appLinkIntent.getData();
|
||||
// End of auto-generated stuff
|
||||
String strangeHost = appLinkData.getHost();
|
||||
SharedPreferences sharedPref = HandlerActivity.this.getSharedPreferences(getString(R.string.server), Context.MODE_PRIVATE);
|
||||
String defaultValue = "none";
|
||||
String server = sharedPref.getString(getString(R.string.server), defaultValue);
|
||||
if (server.equals(request.getUrl().getHost())) {
|
||||
//If the server is the same as the bookwyrm, load it in the webview.
|
||||
return false;
|
||||
} else if (strangeHost.equals(request.getUrl().getHost())) {
|
||||
return false;
|
||||
}
|
||||
// Otherwise, it should go to the default browser instead.
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl());
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
LoadIndicator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -6,13 +6,15 @@ import android.content.SharedPreferences;
|
||||
import android.graphics.Color;
|
||||
import android.security.keystore.KeyGenParameterSpec;
|
||||
import android.security.keystore.KeyProperties;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
//import android.support.v7.app.AppCompatActivity;
|
||||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
|
@ -1,15 +1,31 @@
|
||||
package nl.privacydragon.bookwyrm;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
//import android.support.v7.app.AppCompatActivity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.webkit.JavascriptInterface;
|
||||
import android.webkit.WebResourceRequest;
|
||||
import android.webkit.WebView;
|
||||
import android.webkit.WebViewClient;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@ -29,14 +45,25 @@ import javax.crypto.NoSuchPaddingException;
|
||||
import javax.crypto.spec.GCMParameterSpec;
|
||||
|
||||
public class StartActivity extends AppCompatActivity {
|
||||
|
||||
WebView myWebView;
|
||||
ProgressBar LoadIndicator;
|
||||
@SuppressLint("SetJavaScriptEnabled")
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_start);
|
||||
WebView myWebView = (WebView) findViewById(R.id.webview);
|
||||
LoadIndicator = (ProgressBar) findViewById(R.id.progressBar3);
|
||||
myWebView = (WebView) findViewById(R.id.webview);
|
||||
myWebView.getSettings().setJavaScriptEnabled(true);
|
||||
myWebView.addJavascriptInterface(new Object()
|
||||
{
|
||||
@JavascriptInterface // For API 17+
|
||||
public void performClick()
|
||||
{
|
||||
ScanBarCode();
|
||||
|
||||
}
|
||||
}, "scan");
|
||||
//The user credentials are stored in the shared preferences, so first they have to be read from there.
|
||||
String defaultValue = "none";
|
||||
SharedPreferences sharedPref = StartActivity.this.getSharedPreferences(getString(R.string.server), Context.MODE_PRIVATE);
|
||||
@ -108,16 +135,78 @@ public class StartActivity extends AppCompatActivity {
|
||||
//A webviewclient thing is needed for some stuff. To automatically log in, the credentials are put in the form by the javascript that is loaded once the page is fully loaded. Then it is automatically submitted if the current page is the login page.
|
||||
myWebView.setWebViewClient(new MyWebViewClient(){
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
LoadIndicator.setVisibility(View.GONE);
|
||||
|
||||
view.loadUrl("javascript:(function() { document.getElementById('id_password_confirm').value = '" + passw + "'; ;})()");
|
||||
view.loadUrl("javascript:(function() { document.getElementById('id_localname_confirm').value = '" + name + "'; ;})()");
|
||||
view.loadUrl("javascript:(function() { if (window.location.href == 'https://" + server + "/login') { document.getElementsByName(\"login-confirm\")[0].submit();} ;})()");
|
||||
view.loadUrl("javascript:(function() { " +
|
||||
"const ISBN = document.createElement(\"p\");" +
|
||||
"ISBN.innerHTML = '<br/>Click to scan ISBN';" +
|
||||
"ISBN.addEventListener('click', () => {" +
|
||||
" scan.performClick();" +
|
||||
"});" +
|
||||
"const NewCenter = document.createElement(\"center\");" +
|
||||
"NewCenter.append(ISBN);" +
|
||||
"nav = document.body;" +
|
||||
"nav.insertBefore(NewCenter, nav.children[0]);" +
|
||||
";})()");
|
||||
|
||||
}
|
||||
});
|
||||
//Here, load the login page of the server. That actually does all that is needed.
|
||||
myWebView.loadUrl("https://" + server + "/login");
|
||||
}
|
||||
public void ScanBarCode() {
|
||||
String permission = Manifest.permission.CAMERA;
|
||||
int grant = ContextCompat.checkSelfPermission(StartActivity.this, permission);
|
||||
if (grant != PackageManager.PERMISSION_GRANTED) {
|
||||
String[] permission_list = new String[1];
|
||||
permission_list[0] = permission;
|
||||
ActivityCompat.requestPermissions(StartActivity.this, permission_list, 1);
|
||||
}
|
||||
|
||||
IntentIntegrator intentIntegrator = new IntentIntegrator(StartActivity.this);
|
||||
intentIntegrator.setDesiredBarcodeFormats(intentIntegrator.ALL_CODE_TYPES);
|
||||
intentIntegrator.setBeepEnabled(false);
|
||||
intentIntegrator.setCameraId(0);
|
||||
intentIntegrator.setPrompt("SCAN ISBN");
|
||||
intentIntegrator.setBarcodeImageEnabled(false);
|
||||
intentIntegrator.initiateScan();
|
||||
|
||||
//return "blup";
|
||||
//return "bla";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
IntentResult Result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (Result != null) {
|
||||
if (Result.getContents() == null) {
|
||||
Toast.makeText(this, "cancelled", Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Log.d("MainActivity", "Scanned");
|
||||
myWebView.loadUrl("Javascript:(function() {document.getElementById('search_input').value = " + Result.getContents() + ";" +
|
||||
"document.getElementsByTagName('form')[0].submit(); ;})()");
|
||||
LoadIndicator.setVisibility(View.VISIBLE);
|
||||
|
||||
}
|
||||
} else {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
// Check if the key event was the Back button and if there's history
|
||||
if ((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack()) {
|
||||
myWebView.goBack();
|
||||
return true;
|
||||
}
|
||||
// If it wasn't the Back key or there's no web page history, bubble up to the default
|
||||
// system behavior (probably exit the activity)
|
||||
return super.onKeyDown(keyCode, event);
|
||||
}
|
||||
//Here is code to make sure that links of the bookwyrm server are handled withing the webview client, instead of having it open in the default browser.
|
||||
//Yes, I used the web for this too.
|
||||
private class MyWebViewClient extends WebViewClient {
|
||||
@ -135,5 +224,10 @@ public class StartActivity extends AppCompatActivity {
|
||||
startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPageStarted(WebView view, String url, Bitmap favicon) {
|
||||
LoadIndicator.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
@ -147,4 +147,4 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/button" />
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -1,16 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".StartActivity">
|
||||
|
||||
<WebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar3"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="715dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
3
fastlane/metadata/android/en-US/changelogs/6.txt
Normal file
3
fastlane/metadata/android/en-US/changelogs/6.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Initial release for F-Droid.
|
||||
|
||||
* Added support for four more BookWyrm instances.
|
5
fastlane/metadata/android/en-US/changelogs/7.txt
Normal file
5
fastlane/metadata/android/en-US/changelogs/7.txt
Normal file
@ -0,0 +1,5 @@
|
||||
* Added a loading bar
|
||||
* You can now scan ISBN's, on any instance!
|
||||
|
||||
More technical change:
|
||||
* Mitigated the project to use Androidx libraries, for that is necessary for the ISBN scanning...
|
@ -1,2 +1,10 @@
|
||||
This is a, probably crappy, Android client for BookWyrm.
|
||||
It is just BookWyrm put into a webview element, nothing special.
|
||||
This is an Android client for BookWyrm – a federated social network for tracking your reading, talking about books, writing reviews, and discovering what to read next. It is just BookWyrm put into a webview element, nothing special – but it adds some convenience on top:
|
||||
|
||||
* bookwyrm links can be made to open with the app (e.g. clicking on the link to someone's userprofile will open that from your own bookwyrm instance)
|
||||
* thanks to that, you can immediately follow them easily if you want.
|
||||
* it lets you easily return to your own home timeline when viewing something like posts, on another bookwyrm instance, because the 'back' button is then modified for that.
|
||||
* You can also search for books by scanning the ISBN, no matter what instance of Bookwyrm you use.
|
||||
|
||||
<b>This application is <u>not</u> an official client!</b> (An official client does not exist yet, as far as I know)
|
||||
|
||||
The ISBN scanning feature is created with the zxing-android-embedded library.
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 302 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 329 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 205 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 46 KiB |
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
Normal file
BIN
fastlane/metadata/android/en-US/images/phoneScreenshots/5.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
@ -14,4 +14,7 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# Enables namespacing of each library's R class so that its R class includes only the
|
||||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
@ -10,7 +10,9 @@ dependencyResolutionManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
//maven { url 'https://jitpack.io' }
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "Bookwyrm"
|
||||
include ':app'
|
||||
include ':app'
|
Reference in New Issue
Block a user