6 Commits

Author SHA1 Message Date
b95ddcc811 backup/export und import 2020-01-05 22:59:57 +01:00
90ba3c1134 fix api urls 2020-01-05 22:33:58 +01:00
05174958b2 Added php example 2019-06-30 21:46:28 +02:00
jenkins
24be9b2013 [Jenkins] Increment version 2018-12-14 22:09:01 +01:00
29ce4b727c More fixes for paid mode 2018-12-14 22:07:43 +01:00
jenkins
f178019ffe [Jenkins] Increment version 2018-12-14 19:32:22 +01:00
18 changed files with 408 additions and 130 deletions

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="imageWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="imageAssetPanel">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="launcherLegacy">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetType" value="IMAGE" />
<entry key="cropped" value="true" />
<entry key="iconShape" value="NONE" />
<entry key="imageAsset" value="F:\Eigene Dateien\Dropbox\Programming\Java\AndroidStudioProjects\SimpleCloudNotifier\data\icon_512_nobox.png" />
<entry key="outputName" value="ic_notification_full" />
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="notification">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetType" value="IMAGE" />
<entry key="imageAsset" value="F:\Eigene Dateien\Dropbox\Programming\Java\AndroidStudioProjects\SimpleCloudNotifier\data\icon_512_transparent.png" />
<entry key="outputName" value="ic_notification_white" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="outputIconType" value="LAUNCHER_LEGACY" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="assetSourceType" value="FILE" />
<entry key="outputName" value="ic_share" />
<entry key="sourceFile" value="C:\Users\Mike\Downloads\baseline-share-24px.svg" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

View File

@@ -1,29 +1,113 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="XML">
<arrangement>
<rules>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:android</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>xmlns:.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:id</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*:name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>name</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>style</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>^$</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
</AND>
</match>
<order>ANDROID_ATTRIBUTE_ORDER</order>
</rule>
</section>
<section>
<rule>
<match>
<AND>
<NAME>.*</NAME>
<XML_ATTRIBUTE />
<XML_NAMESPACE>.*</XML_NAMESPACE>
</AND>
</match>
<order>BY_NAME</order>
</rule>
</section>
</rules>
</arrangement>
</codeStyleSettings>
</code_scheme>
</component>

View File

@@ -24,6 +24,15 @@
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.blackforestbytes.simplecloudnotifier.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" />
</provider>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/icon" />

View File

@@ -35,6 +35,11 @@ public class CMessageList
}
private CMessageList()
{
reloadPrefs();
}
public void reloadPrefs()
{
synchronized (msg_lock)
{

View File

@@ -15,9 +15,9 @@ public class QueryLog
private final static int MAX_HISTORY_SIZE = 192;
private static QueryLog _instance;
public static QueryLog instance() { if (_instance == null) synchronized (QueryLog.class) { if (_instance == null) _instance = new QueryLog(); } return _instance; }
public static QueryLog inst() { if (_instance == null) synchronized (QueryLog.class) { if (_instance == null) _instance = new QueryLog(); } return _instance; }
private QueryLog(){ load(); }
private QueryLog(){ reloadPrefs(); }
private final List<SingleQuery> history = new ArrayList<>();
@@ -50,7 +50,7 @@ public class QueryLog
e.apply();
}
public synchronized void load()
public synchronized void reloadPrefs()
{
try
{

View File

@@ -62,6 +62,11 @@ public class SCNSettings
// ------------------------------------------------------------
public SCNSettings()
{
reloadPrefs();
}
public void reloadPrefs()
{
SharedPreferences sharedPref = SCNApp.getContext().getSharedPreferences("Config", Context.MODE_PRIVATE);
@@ -122,6 +127,9 @@ public class SCNSettings
e.putString( "user_key", user_key);
e.putString( "fcm_token_local", fcm_token_local);
e.putString( "fcm_token_server", fcm_token_server);
e.putBoolean("promode_local", promode_local);
e.putBoolean("promode_server", promode_server);
e.putString( "promode_token", promode_token);
e.putBoolean("app_enabled", Enabled);
e.putInt( "local_cache_size", LocalCacheSize);
@@ -244,15 +252,16 @@ public class SCNSettings
public void updateProState(View loader)
{
Tuple3<Boolean, Boolean, String> state = IABService.inst().getPurchaseCachedExtended(IABService.IAB_PRO_MODE);
if (!state.Item2) return; // not nitialized
if (!state.Item2) return; // not initialized
boolean promode_real = state.Item1;
if (promode_real != promode_local || promode_real != promode_server)
{
promode_local = promode_real;
promode_token = promode_real ? state.Item3 : "";
save();
updateProStateOnServer(loader);
}
}

View File

@@ -105,7 +105,7 @@ public class ServerCommunication
try
{
Request request = new Request.Builder()
.url(BASE_URL + "updateFCMToken.php?user_id="+id+"&user_key="+key+"&fcm_token="+token)
.url(BASE_URL + "update.php?user_id="+id+"&user_key="+key+"&fcm_token="+token)
.build();
client.newCall(request).enqueue(new Callback()
@@ -172,7 +172,7 @@ public class ServerCommunication
try
{
Request request = new Request.Builder()
.url(BASE_URL + "updateFCMToken.php?user_id=" + id + "&user_key=" + key)
.url(BASE_URL + "update.php?user_id=" + id + "&user_key=" + key)
.build();
client.newCall(request).enqueue(new Callback() {
@@ -613,7 +613,7 @@ public class ServerCommunication
LogLevel l = LogLevel.INFO;
SingleQuery q = new SingleQuery(l, i, s, u, r, rc, "SUCCESS");
QueryLog.instance().add(q);
QueryLog.inst().add(q);
}
catch (Exception e2)
{
@@ -644,7 +644,7 @@ public class ServerCommunication
LogLevel l = isio?LogLevel.WARN:LogLevel.ERROR;
SingleQuery q = new SingleQuery(l, i, s, u, r, rc, e.toString());
QueryLog.instance().add(q);
QueryLog.inst().add(q);
}
catch (Exception e2)
{

View File

@@ -4,8 +4,6 @@ import android.util.Log;
import android.widget.Toast;
import com.blackforestbytes.simplecloudnotifier.SCNApp;
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple4;
import com.blackforestbytes.simplecloudnotifier.lib.datatypes.Tuple5;
import com.blackforestbytes.simplecloudnotifier.lib.string.Str;
import com.blackforestbytes.simplecloudnotifier.model.CMessage;
import com.blackforestbytes.simplecloudnotifier.model.CMessageList;
@@ -15,7 +13,6 @@ import com.blackforestbytes.simplecloudnotifier.model.QueryLog;
import com.blackforestbytes.simplecloudnotifier.model.SCNSettings;
import com.blackforestbytes.simplecloudnotifier.model.ServerCommunication;
import com.blackforestbytes.simplecloudnotifier.model.SingleQuery;
import com.google.android.gms.common.util.JsonUtils;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
@@ -52,7 +49,7 @@ public class FBMService extends FirebaseMessagingService
SingleQuery q = new SingleQuery(LogLevel.INFO, Instant.now(), "FBM<recieve>", Str.Empty, new JSONObject(remoteMessage.getData()).toString(), 0, "SUCCESS");
QueryLog.instance().add(q);
QueryLog.inst().add(q);
if (trimmed)
{

View File

@@ -74,6 +74,11 @@ public class IABService implements PurchasesUpdatedListener
startServiceConnection(this::queryPurchases, false);
}
public void reloadPrefs()
{
loadCache();
}
private void loadCache()
{
_localCache.clear();

View File

@@ -1,11 +1,13 @@
package com.blackforestbytes.simplecloudnotifier.view;
import android.content.Context;
import android.content.Intent;
import android.icu.text.SymbolTable;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.blackforestbytes.simplecloudnotifier.R;
@@ -23,6 +25,12 @@ import androidx.appcompat.widget.Toolbar;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Map;
import java.util.Set;
public class MainActivity extends AppCompatActivity
{
public TabAdapter adpTabs;
@@ -31,7 +39,7 @@ public class MainActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
QueryLog.instance();
QueryLog.inst();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@@ -103,4 +111,114 @@ public class MainActivity extends AppCompatActivity
if (clickCount == 4) startActivity(new Intent(this, QueryLogActivity.class));
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1991 && resultCode == RESULT_OK)
{
Uri uri = data.getData(); //The uri with the location of the file
Context ctxt = this;
try
{
ObjectInputStream stream = new ObjectInputStream(getContentResolver().openInputStream(uri));
Map<String, ?> d1 = (Map<String, ?>)stream.readObject();
Map<String, ?> d2 = (Map<String, ?>)stream.readObject();
Map<String, ?> d3 = (Map<String, ?>)stream.readObject();
Map<String, ?> d4 = (Map<String, ?>)stream.readObject();
stream.close();
runOnUiThread(() ->
{
SharedPreferences.Editor e1 = ctxt.getSharedPreferences("Config", Context.MODE_PRIVATE).edit();
SharedPreferences.Editor e2 = ctxt.getSharedPreferences("IAB", Context.MODE_PRIVATE).edit();
SharedPreferences.Editor e3 = ctxt.getSharedPreferences("CMessageList", Context.MODE_PRIVATE).edit();
SharedPreferences.Editor e4 = ctxt.getSharedPreferences("QueryLog", Context.MODE_PRIVATE).edit();
e1.clear();
for (Map.Entry<String, ?> entry : d1.entrySet())
{
if (entry.getValue() instanceof String) e1.putString(entry.getKey(), (String)entry.getValue());
if (entry.getValue() instanceof Boolean) e1.putBoolean(entry.getKey(), (Boolean)entry.getValue());
if (entry.getValue() instanceof Float) e1.putFloat(entry.getKey(), (Float)entry.getValue());
if (entry.getValue() instanceof Integer) e1.putInt(entry.getKey(), (Integer)entry.getValue());
if (entry.getValue() instanceof Long) e1.putLong(entry.getKey(), (Long)entry.getValue());
if (entry.getValue() instanceof Set<?>) e1.putStringSet(entry.getKey(), (Set<String>)entry.getValue());
}
e2.clear();
for (Map.Entry<String, ?> entry : d2.entrySet())
{
if (entry.getValue() instanceof String) e2.putString(entry.getKey(), (String)entry.getValue());
if (entry.getValue() instanceof Boolean) e2.putBoolean(entry.getKey(), (Boolean)entry.getValue());
if (entry.getValue() instanceof Float) e2.putFloat(entry.getKey(), (Float)entry.getValue());
if (entry.getValue() instanceof Integer) e2.putInt(entry.getKey(), (Integer)entry.getValue());
if (entry.getValue() instanceof Long) e2.putLong(entry.getKey(), (Long)entry.getValue());
if (entry.getValue() instanceof Set<?>) e2.putStringSet(entry.getKey(), (Set<String>)entry.getValue());
}
e2.clear();
for (Map.Entry<String, ?> entry : d3.entrySet())
{
if (entry.getValue() instanceof String) e3.putString(entry.getKey(), (String)entry.getValue());
if (entry.getValue() instanceof Boolean) e3.putBoolean(entry.getKey(), (Boolean)entry.getValue());
if (entry.getValue() instanceof Float) e3.putFloat(entry.getKey(), (Float)entry.getValue());
if (entry.getValue() instanceof Integer) e3.putInt(entry.getKey(), (Integer)entry.getValue());
if (entry.getValue() instanceof Long) e3.putLong(entry.getKey(), (Long)entry.getValue());
if (entry.getValue() instanceof Set<?>) e3.putStringSet(entry.getKey(), (Set<String>)entry.getValue());
}
e4.clear();
for (Map.Entry<String, ?> entry : d4.entrySet())
{
if (entry.getValue() instanceof String) e4.putString(entry.getKey(), (String)entry.getValue());
if (entry.getValue() instanceof Boolean) e4.putBoolean(entry.getKey(), (Boolean)entry.getValue());
if (entry.getValue() instanceof Float) e4.putFloat(entry.getKey(), (Float)entry.getValue());
if (entry.getValue() instanceof Integer) e4.putInt(entry.getKey(), (Integer)entry.getValue());
if (entry.getValue() instanceof Long) e4.putLong(entry.getKey(), (Long)entry.getValue());
if (entry.getValue() instanceof Set<?>) e4.putStringSet(entry.getKey(), (Set<String>)entry.getValue());
}
e1.apply();
e2.apply();
e3.apply();
e4.apply();
SCNSettings.inst().reloadPrefs();
IABService.inst().reloadPrefs();
CMessageList.inst().reloadPrefs();
QueryLog.inst().reloadPrefs();
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ViewPager viewPager = findViewById(R.id.pager);
PagerAdapter adapter = adpTabs = new TabAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.tab_layout);
tabLayout.setupWithViewPager(viewPager);
SCNSettings.inst().work(this);
SCNApp.showToast("Backup imported", Toast.LENGTH_LONG);
finish();
});
}
catch (Exception e)
{
Log.e("Import:Err", e.toString());
SCNApp.showToast("Import failed", Toast.LENGTH_LONG);
}
}
}
}

View File

@@ -2,6 +2,8 @@ package com.blackforestbytes.simplecloudnotifier.view;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.AudioManager;
@@ -11,6 +13,7 @@ import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.util.Log;
import android.view.LayoutInflater;
@@ -28,6 +31,7 @@ import android.widget.TextView;
import android.widget.Toast;
import com.android.billingclient.api.Purchase;
import com.blackforestbytes.simplecloudnotifier.BuildConfig;
import com.blackforestbytes.simplecloudnotifier.R;
import com.blackforestbytes.simplecloudnotifier.SCNApp;
import com.blackforestbytes.simplecloudnotifier.lib.android.ThreadUtils;
@@ -39,9 +43,15 @@ import com.blackforestbytes.simplecloudnotifier.util.TextChangedListener;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.Map;
import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;
import androidx.fragment.app.Fragment;
import top.defaults.colorpicker.ColorPickerPopup;
import xyz.aprildown.ultimatemusicpicker.MusicPickerListener;
@@ -93,6 +103,9 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
private SeekBar prefMsgHighVolume;
private ImageView prefMsgHighVolumeTest;
private Button prefBtnImport;
private Button prefBtnExport;
private int musicPickerSwitch = -1;
private MediaPlayer[] mPlayers = new MediaPlayer[3];
@@ -160,6 +173,9 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
prefMsgHighVolume = v.findViewById(R.id.prefMsgHighVolume);
prefMsgHighVolumeTest = v.findViewById(R.id.btnHighVolumeTest);
prefBtnExport = v.findViewById(R.id.prefExport);
prefBtnImport = v.findViewById(R.id.prefImport);
ArrayAdapter<Integer> plcsa = new ArrayAdapter<>(v.getContext(), android.R.layout.simple_spinner_item, SCNSettings.CHOOSABLE_CACHE_SIZES);
plcsa.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
prefLocalCacheSize.setAdapter(plcsa);
@@ -246,6 +262,9 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
prefUpgradeAccount.setOnClickListener(a -> onUpgradeAccount());
prefBtnExport.setOnClickListener(a -> onExport());
prefBtnImport.setOnClickListener(a -> onImport());
prefMsgLowEnableSound.setOnCheckedChangeListener((a,b) -> { s.PriorityLow.EnableSound=b; saveAndUpdate(); });
prefMsgLowRingtone_container.setOnClickListener(a -> chooseRingtoneLow());
prefMsgLowRepeatSound.setOnCheckedChangeListener((a,b) -> { s.PriorityLow.RepeatSound=b; saveAndUpdate(); });
@@ -277,6 +296,55 @@ public class SettingsFragment extends Fragment implements MusicPickerListener
prefMsgHighVolumeTest.setOnClickListener((v) -> { if (s.PriorityHigh.ForceVolume) playTestSound(2, prefMsgHighVolumeTest, s.PriorityHigh.SoundSource, s.PriorityHigh.ForceVolumeValue); });
}
private void onExport()
{
Context ctxt = getContext();
if (ctxt == null) return;
try
{
File outputDir = ctxt.getCacheDir(); // context being the Activity pointer
File outputFile = File.createTempFile("scn_export_", ".dat", outputDir);
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(outputFile));
Map<String, ?> d1 = ctxt.getSharedPreferences("Config", Context.MODE_PRIVATE).getAll();
Map<String, ?> d2 = ctxt.getSharedPreferences("IAB", Context.MODE_PRIVATE).getAll();
Map<String, ?> d3 = ctxt.getSharedPreferences("CMessageList", Context.MODE_PRIVATE).getAll();
Map<String, ?> d4 = ctxt.getSharedPreferences("QueryLog", Context.MODE_PRIVATE).getAll();
output.writeObject(d1);
output.writeObject(d2);
output.writeObject(d3);
output.writeObject(d4);
Intent intent = new Intent(Intent.ACTION_SEND);
Uri uri = FileProvider.getUriForFile(ctxt, "com.blackforestbytes.simplecloudnotifier.fileprovider", outputFile);
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.setType("*/*");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "Export"));
}
catch (IOException e)
{
Log.e("Export:Err", e.toString());
SCNApp.showToast("Export failed", Toast.LENGTH_LONG);
}
}
private void onImport()
{
SCNApp.getMainActivity().setContentView(R.layout.activity_main);
Intent intent = new Intent()
.setType("*/*")
.setAction(Intent.ACTION_GET_CONTENT);
((MainActivity)getActivity()).startActivityForResult(Intent.createChooser(intent, "Select a file"), 1991);
}
private void updateEnabled(boolean prev, boolean now)
{
if (!prev && now)

View File

@@ -22,7 +22,7 @@ public class QueryLogActivity extends AppCompatActivity
setContentView(R.layout.activity_querylog);
ListView lvMain = findViewById(R.id.lvQueryList);
SingleQuery[] arr = QueryLog.instance().get().toArray(new SingleQuery[0]);
SingleQuery[] arr = QueryLog.inst().get().toArray(new SingleQuery[0]);
QueryLogAdapter a = new QueryLogAdapter(this, arr);
lvMain.setAdapter(a);

View File

@@ -805,6 +805,24 @@
</androidx.cardview.widget.CardView>
<com.google.android.material.button.MaterialButton
android:id="@+id/prefExport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
app:cornerRadius="0dp"
android:backgroundTint="#444444"
android:text="@string/export_settings" />
<com.google.android.material.button.MaterialButton
android:id="@+id/prefImport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="12dp"
app:cornerRadius="0dp"
android:backgroundTint="#666666"
android:text="@string/import_settings" />
</LinearLayout>
</ScrollView>

View File

@@ -37,4 +37,6 @@
<string name="play_test_sound">Play test sound</string>
<string name="delete">DELETE</string>
<string name="title_activity_query_log">QueryLogActivity</string>
<string name="import_settings">Import settings</string>
<string name="export_settings">Export settings</string>
</resources>

View File

@@ -0,0 +1,7 @@
<paths>
<files-path path="/" name="files" />
<cache-path path="/" name="cache" />
<external-path path="/" name="external" />
<external-files-path path="/" name="external-files" />
<external-cache-path path="/" name="external-cache" />
</paths>

View File

@@ -1,3 +1,3 @@
#Fri Dec 14 18:37:41 CET 2018
VERSION_NAME=1.4.0
VERSION_CODE=18
#Fri Dec 14 22:08:16 CET 2018
VERSION_NAME=1.6.0
VERSION_CODE=20

35
examples/scn_send.php Normal file
View File

@@ -0,0 +1,35 @@
<?php
/**
* @param string $title
* @param string $content
* @param int $priority
* @return bool
*/
function sendSCN($title, $content, $priority) {
global $config;
$data =
[
'user_id' => '', //TODO set your userid
'user_key' => '', //TODO set your userkey
'title' => $title,
'content' => $content,
'priority' => $priority,
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://simplecloudnotifier.blackforestbytes.com/send.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
if ($result === false) return false;
$json = json_decode($result, true);
return $json['success'];
}

View File

@@ -166,6 +166,12 @@ function verifyOrderToken($tok)
{
// https://developers.google.com/android-publisher/api-ref/purchases/products/get
// if this does no longer work, you probably have to go through the initial OAuth process again
// 1. go to Postman do the [ https://accounts.google.com/o/oauth2/auth ] request (in browser) to get a new "code"
// 2. go to Postman do the [ Get Tokens ] request to get a new "access_token" and "access_token"
// 3. update these tokens in the server config.php
try
{
$package = getConfig()['verify_api']['package_name'];