mirror of https://github.com/M66B/NetGuard.git
Android O compatibility
This commit is contained in:
parent
8cd746e0d4
commit
9aef8e8ef0
83
app/app.iml
83
app/app.iml
|
@ -50,6 +50,13 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/renderscript" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/allDebug/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/all/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/all/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/assets" type="java-test-resource" />
|
||||
|
@ -58,13 +65,6 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAllDebug/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/all/debug" isTestSource="true" generated="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/all/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/all/debug" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/all/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/all/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/all/assets" type="java-resource" />
|
||||
|
@ -72,14 +72,6 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/all/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/all/renderscript" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/all/shaders" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/assets" type="java-test-resource" />
|
||||
|
@ -88,6 +80,14 @@
|
|||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/testAll/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/res" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/resources" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/assets" type="java-test-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/aidl" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/jni" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/rs" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/androidTestAll/shaders" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
|
||||
|
@ -143,36 +143,35 @@
|
|||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="play-services-basement-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-ads-lite-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-core-ui-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-ads-lite-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="picasso-2.5.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-ads-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-iid-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-core-ui-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-ads-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-gass-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-core-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-core-utils-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-fragment-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-base-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-clearcut-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-safetynet-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-analytics-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-media-compat-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="recyclerview-v7-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-common-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-analytics-impl-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-tasks-11.0.2" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-vector-drawable-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-compat-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="animated-vector-drawable-25.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-media-compat-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-core-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-ads-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-vector-drawable-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-iid-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-core-utils-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="recyclerview-v7-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-ads-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-safetynet-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-basement-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-base-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-gass-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-fragment-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="animated-vector-drawable-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-compat-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-clearcut-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-26.0.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-analytics-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-analytics-impl-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="play-services-tasks-11.0.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="firebase-common-11.0.4" level="project" />
|
||||
</component>
|
||||
</module>
|
|
@ -2,7 +2,7 @@ apply plugin: 'com.android.model.application'
|
|||
|
||||
model {
|
||||
android {
|
||||
compileSdkVersion = 25
|
||||
compileSdkVersion = 26
|
||||
buildToolsVersion = "26.0.1"
|
||||
|
||||
defaultConfig {
|
||||
|
@ -57,14 +57,14 @@ model {
|
|||
create("all") {
|
||||
versionName = "2.114"
|
||||
minSdkVersion.apiLevel = 14
|
||||
targetSdkVersion.apiLevel = 25
|
||||
targetSdkVersion.apiLevel = 26
|
||||
versionCode = 2017072501
|
||||
archivesBaseName = "NetGuard-v$versionName"
|
||||
}
|
||||
create("lollipop-and-later") {
|
||||
versionName = "2.114"
|
||||
minSdkVersion.apiLevel = 20
|
||||
targetSdkVersion.apiLevel = 25
|
||||
targetSdkVersion.apiLevel = 26
|
||||
versionCode = 2017072511
|
||||
archivesBaseName = "NetGuard-v$versionName"
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ model {
|
|||
versionName = "2.114"
|
||||
minSdkVersion.apiLevel = 14
|
||||
maxSdkVersion = 19
|
||||
targetSdkVersion.apiLevel = 25
|
||||
targetSdkVersion.apiLevel = 26
|
||||
versionCode = 2017072521
|
||||
archivesBaseName = "NetGuard-v$versionName"
|
||||
}
|
||||
|
@ -82,9 +82,8 @@ model {
|
|||
|
||||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
compile 'com.android.support:appcompat-v7:25.+'
|
||||
compile 'com.android.support:support-annotations:25.+'
|
||||
compile 'com.android.support:recyclerview-v7:25.+'
|
||||
compile 'com.android.support:appcompat-v7:26.0.+'
|
||||
compile 'com.android.support:recyclerview-v7:26.0.+'
|
||||
compile 'com.squareup.picasso:picasso:2.5.+'
|
||||
compile 'com.google.firebase:firebase-core:11.0.+'
|
||||
compile 'com.google.firebase:firebase-ads:11.0.+'
|
||||
|
|
|
@ -20,6 +20,10 @@ package eu.faircode.netguard;
|
|||
*/
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.media.AudioAttributes;
|
||||
import android.util.Log;
|
||||
|
||||
public class ApplicationEx extends Application {
|
||||
|
@ -32,6 +36,18 @@ public class ApplicationEx extends Application {
|
|||
super.onCreate();
|
||||
Log.i(TAG, "Create version=" + Util.getSelfVersionName(this) + "/" + Util.getSelfVersionCode(this));
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationChannel foreground = new NotificationChannel("foreground", getString(R.string.app_name), NotificationManager.IMPORTANCE_MIN);
|
||||
foreground.setSound(null, new AudioAttributes.Builder().build());
|
||||
nm.createNotificationChannel(foreground);
|
||||
|
||||
NotificationChannel notify = new NotificationChannel("notify", getString(R.string.app_name), NotificationManager.IMPORTANCE_DEFAULT);
|
||||
notify.setSound(null, new AudioAttributes.Builder().build());
|
||||
nm.createNotificationChannel(notify);
|
||||
}
|
||||
|
||||
mPrevHandler = Thread.getDefaultUncaughtExceptionHandler();
|
||||
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
|
||||
@Override
|
||||
|
|
|
@ -20,9 +20,12 @@ package eu.faircode.netguard;
|
|||
*/
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -48,76 +51,92 @@ public class ServiceExternal extends IntentService {
|
|||
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
Log.i(TAG, "Received " + intent);
|
||||
Util.logExtras(intent);
|
||||
try {
|
||||
startForeground(ServiceSinkhole.NOTIFY_EXTERNAL, getForegroundNotification(this));
|
||||
|
||||
if (ACTION_DOWNLOAD_HOSTS_FILE.equals(intent.getAction())) {
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
Log.i(TAG, "Received " + intent);
|
||||
Util.logExtras(intent);
|
||||
|
||||
String hosts_url = prefs.getString("hosts_url", null);
|
||||
File tmp = new File(getFilesDir(), "hosts.tmp");
|
||||
File hosts = new File(getFilesDir(), "hosts.txt");
|
||||
if (ACTION_DOWNLOAD_HOSTS_FILE.equals(intent.getAction())) {
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
URLConnection connection = null;
|
||||
try {
|
||||
URL url = new URL(hosts_url);
|
||||
connection = url.openConnection();
|
||||
connection.connect();
|
||||
String hosts_url = prefs.getString("hosts_url", null);
|
||||
File tmp = new File(getFilesDir(), "hosts.tmp");
|
||||
File hosts = new File(getFilesDir(), "hosts.txt");
|
||||
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
HttpURLConnection httpConnection = (HttpURLConnection) connection;
|
||||
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK)
|
||||
throw new IOException(httpConnection.getResponseCode() + " " + httpConnection.getResponseMessage());
|
||||
}
|
||||
|
||||
int contentLength = connection.getContentLength();
|
||||
Log.i(TAG, "Content length=" + contentLength);
|
||||
in = connection.getInputStream();
|
||||
out = new FileOutputStream(tmp);
|
||||
|
||||
long size = 0;
|
||||
byte buffer[] = new byte[4096];
|
||||
int bytes;
|
||||
while ((bytes = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytes);
|
||||
size += bytes;
|
||||
}
|
||||
|
||||
Log.i(TAG, "Downloaded size=" + size);
|
||||
|
||||
if (hosts.exists())
|
||||
hosts.delete();
|
||||
tmp.renameTo(hosts);
|
||||
|
||||
String last = SimpleDateFormat.getDateTimeInstance().format(new Date().getTime());
|
||||
prefs.edit().putString("hosts_last_download", last).apply();
|
||||
|
||||
ServiceSinkhole.reload("hosts file download", this, false);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
|
||||
if (tmp.exists())
|
||||
tmp.delete();
|
||||
} finally {
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
URLConnection connection = null;
|
||||
try {
|
||||
if (out != null)
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
try {
|
||||
if (in != null)
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
URL url = new URL(hosts_url);
|
||||
connection = url.openConnection();
|
||||
connection.connect();
|
||||
|
||||
if (connection instanceof HttpURLConnection)
|
||||
((HttpURLConnection) connection).disconnect();
|
||||
if (connection instanceof HttpURLConnection) {
|
||||
HttpURLConnection httpConnection = (HttpURLConnection) connection;
|
||||
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK)
|
||||
throw new IOException(httpConnection.getResponseCode() + " " + httpConnection.getResponseMessage());
|
||||
}
|
||||
|
||||
int contentLength = connection.getContentLength();
|
||||
Log.i(TAG, "Content length=" + contentLength);
|
||||
in = connection.getInputStream();
|
||||
out = new FileOutputStream(tmp);
|
||||
|
||||
long size = 0;
|
||||
byte buffer[] = new byte[4096];
|
||||
int bytes;
|
||||
while ((bytes = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytes);
|
||||
size += bytes;
|
||||
}
|
||||
|
||||
Log.i(TAG, "Downloaded size=" + size);
|
||||
|
||||
if (hosts.exists())
|
||||
hosts.delete();
|
||||
tmp.renameTo(hosts);
|
||||
|
||||
String last = SimpleDateFormat.getDateTimeInstance().format(new Date().getTime());
|
||||
prefs.edit().putString("hosts_last_download", last).apply();
|
||||
|
||||
ServiceSinkhole.reload("hosts file download", this, false);
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
|
||||
if (tmp.exists())
|
||||
tmp.delete();
|
||||
} finally {
|
||||
try {
|
||||
if (out != null)
|
||||
out.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
try {
|
||||
if (in != null)
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
Log.e(TAG, ex.toString() + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
||||
if (connection instanceof HttpURLConnection)
|
||||
((HttpURLConnection) connection).disconnect();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
stopForeground(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static Notification getForegroundNotification(Context context) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "foreground");
|
||||
builder.setSmallIcon(R.drawable.ic_hourglass_empty_white_24dp);
|
||||
builder.setPriority(NotificationCompat.PRIORITY_MIN);
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS);
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
builder.setContentTitle(context.getString(R.string.app_name));
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,7 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
private static final int NOTIFY_ERROR = 5;
|
||||
private static final int NOTIFY_TRAFFIC = 6;
|
||||
private static final int NOTIFY_UPDATE = 7;
|
||||
public static final int NOTIFY_EXTERNAL = 8;
|
||||
|
||||
public static final String EXTRA_COMMAND = "Command";
|
||||
private static final String EXTRA_REASON = "Reason";
|
||||
|
@ -365,7 +366,11 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
if (cmd == Command.start || cmd == Command.reload) {
|
||||
Intent watchdogIntent = new Intent(ServiceSinkhole.this, ServiceSinkhole.class);
|
||||
watchdogIntent.setAction(ACTION_WATCHDOG);
|
||||
PendingIntent pi = PendingIntent.getService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent pi;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
pi = PendingIntent.getForegroundService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
else
|
||||
pi = PendingIntent.getService(ServiceSinkhole.this, 1, watchdogIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
am.cancel(pi);
|
||||
|
@ -994,8 +999,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(ServiceSinkhole.this)
|
||||
.setWhen(when)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(ServiceSinkhole.this, "notify");
|
||||
builder.setWhen(when)
|
||||
.setSmallIcon(R.drawable.ic_equalizer_white_24dp)
|
||||
.setContent(remoteViews)
|
||||
.setContentIntent(pi)
|
||||
|
@ -1003,10 +1008,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setOngoing(true)
|
||||
.setAutoCancel(false);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
|
||||
if (state == State.none || state == State.waiting) {
|
||||
if (state != State.none) {
|
||||
|
@ -2041,8 +2045,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
.setContentIntent(pi)
|
||||
.setColor(tv.data)
|
||||
.setAutoCancel(true);
|
||||
|
@ -2055,8 +2059,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setContentText(getString(R.string.msg_installed, name));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
// Get defaults
|
||||
SharedPreferences prefs_wifi = getSharedPreferences("wifi", Context.MODE_PRIVATE);
|
||||
|
@ -2243,7 +2247,11 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
// Setup house holding
|
||||
Intent alarmIntent = new Intent(this, ServiceSinkhole.class);
|
||||
alarmIntent.setAction(ACTION_HOUSE_HOLDING);
|
||||
PendingIntent pi = PendingIntent.getService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
PendingIntent pi;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
pi = PendingIntent.getForegroundService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
else
|
||||
pi = PendingIntent.getService(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||
am.setInexactRepeating(AlarmManager.RTC, SystemClock.elapsedRealtime() + 60 * 1000, AlarmManager.INTERVAL_HALF_DAY, pi);
|
||||
|
@ -2425,8 +2433,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(isLockedDown(last_metered) ? R.drawable.ic_lock_outline_white_24dp : R.drawable.ic_security_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "foreground");
|
||||
builder.setSmallIcon(isLockedDown(last_metered) ? R.drawable.ic_lock_outline_white_24dp : R.drawable.ic_security_white_24dp)
|
||||
.setContentIntent(pi)
|
||||
.setColor(tv.data)
|
||||
.setOngoing(true)
|
||||
|
@ -2438,11 +2446,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
builder.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_started));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET)
|
||||
.setPriority(Notification.PRIORITY_MIN);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
|
||||
.setPriority(NotificationCompat.PRIORITY_MIN);
|
||||
|
||||
if (allowed > 0 || blocked > 0 || hosts > 0) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
|
@ -2477,8 +2484,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "foreground");
|
||||
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
.setContentIntent(pi)
|
||||
.setColor(tv.data)
|
||||
.setOngoing(true)
|
||||
|
@ -2490,11 +2497,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
builder.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_waiting));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET)
|
||||
.setPriority(Notification.PRIORITY_MIN);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
|
||||
.setPriority(NotificationCompat.PRIORITY_MIN);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -2505,8 +2511,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_revoked))
|
||||
.setContentIntent(pi)
|
||||
|
@ -2514,10 +2520,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setOngoing(false)
|
||||
.setAutoCancel(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
|
||||
notification.bigText(getString(R.string.msg_revoked));
|
||||
|
@ -2532,8 +2537,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_autostart))
|
||||
.setContentIntent(pi)
|
||||
|
@ -2541,10 +2546,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setOngoing(false)
|
||||
.setAutoCancel(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
|
||||
notification.bigText(getString(R.string.msg_autostart));
|
||||
|
@ -2558,8 +2562,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_error_white_24dp)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_error, message))
|
||||
.setContentIntent(pi)
|
||||
|
@ -2567,10 +2571,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setOngoing(false)
|
||||
.setAutoCancel(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
|
||||
notification.bigText(getString(R.string.msg_error, message));
|
||||
|
@ -2592,8 +2595,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
getTheme().resolveAttribute(R.attr.colorOff, tv, true);
|
||||
int colorOff = tv.data;
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_cloud_upload_white_24dp)
|
||||
.setGroup("AccessAttempt")
|
||||
.setContentIntent(pi)
|
||||
.setColor(colorOff)
|
||||
|
@ -2607,10 +2610,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
builder.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_access, name));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
DateFormat df = new SimpleDateFormat("dd HH:mm");
|
||||
|
||||
|
@ -2662,8 +2664,8 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
|
||||
TypedValue tv = new TypedValue();
|
||||
getTheme().resolveAttribute(R.attr.colorPrimary, tv, true);
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "notify");
|
||||
builder.setSmallIcon(R.drawable.ic_security_white_24dp)
|
||||
.setContentTitle(getString(R.string.app_name))
|
||||
.setContentText(getString(R.string.msg_update))
|
||||
.setContentIntent(pi)
|
||||
|
@ -2671,10 +2673,9 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
.setOngoing(false)
|
||||
.setAutoCancel(true);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
builder.setCategory(Notification.CATEGORY_STATUS)
|
||||
.setVisibility(Notification.VISIBILITY_SECRET);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(NotificationCompat.CATEGORY_STATUS)
|
||||
.setVisibility(NotificationCompat.VISIBILITY_SECRET);
|
||||
|
||||
NotificationCompat.BigTextStyle notification = new NotificationCompat.BigTextStyle(builder);
|
||||
notification.bigText(getString(R.string.msg_update));
|
||||
|
@ -2816,14 +2817,20 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
Intent intent = new Intent(context, ServiceSinkhole.class);
|
||||
intent.putExtra(EXTRA_COMMAND, Command.run);
|
||||
intent.putExtra(EXTRA_REASON, reason);
|
||||
context.startService(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(intent);
|
||||
else
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
public static void start(String reason, Context context) {
|
||||
Intent intent = new Intent(context, ServiceSinkhole.class);
|
||||
intent.putExtra(EXTRA_COMMAND, Command.start);
|
||||
intent.putExtra(EXTRA_REASON, reason);
|
||||
context.startService(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(intent);
|
||||
else
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
public static void reload(String reason, Context context, boolean interactive) {
|
||||
|
@ -2833,7 +2840,10 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
intent.putExtra(EXTRA_COMMAND, Command.reload);
|
||||
intent.putExtra(EXTRA_REASON, reason);
|
||||
intent.putExtra(EXTRA_INTERACTIVE, interactive);
|
||||
context.startService(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(intent);
|
||||
else
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2842,13 +2852,19 @@ public class ServiceSinkhole extends VpnService implements SharedPreferences.OnS
|
|||
intent.putExtra(EXTRA_COMMAND, Command.stop);
|
||||
intent.putExtra(EXTRA_REASON, reason);
|
||||
intent.putExtra(EXTRA_TEMPORARY, vpnonly);
|
||||
context.startService(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(intent);
|
||||
else
|
||||
context.startService(intent);
|
||||
}
|
||||
|
||||
public static void reloadStats(String reason, Context context) {
|
||||
Intent intent = new Intent(context, ServiceSinkhole.class);
|
||||
intent.putExtra(EXTRA_COMMAND, Command.stats);
|
||||
intent.putExtra(EXTRA_REASON, reason);
|
||||
context.startService(intent);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(intent);
|
||||
else
|
||||
context.startService(intent);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
android:id="@+id/tvTx"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:typeface="monospace" />
|
||||
|
||||
<TextView
|
||||
|
@ -25,7 +25,7 @@
|
|||
android:layout_marginStart="4dp"
|
||||
android:alpha="0.5"
|
||||
android:text="▲"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textColor="@color/colorSend" />
|
||||
|
||||
<TextView
|
||||
|
@ -34,7 +34,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:typeface="monospace" />
|
||||
|
||||
<TextView
|
||||
|
@ -44,7 +44,7 @@
|
|||
android:layout_marginStart="4dp"
|
||||
android:alpha="0.5"
|
||||
android:text="▼"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textColor="@color/colorReceive" />
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -55,7 +55,7 @@
|
|||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -66,7 +66,7 @@
|
|||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:singleLine="false"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<TextView
|
||||
|
@ -76,7 +76,7 @@
|
|||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textSize="10sp" />
|
||||
|
||||
<ImageView
|
||||
|
@ -96,7 +96,7 @@
|
|||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:paddingTop="10sp"
|
||||
android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Notification.Info"
|
||||
android:textColor="@color/colorGrayed"
|
||||
android:textSize="10sp"
|
||||
android:typeface="monospace" />
|
||||
|
|
|
@ -7,7 +7,7 @@ buildscript {
|
|||
dependencies {
|
||||
// http://tools.android.com/tech-docs/new-build-system/gradle-experimental
|
||||
classpath 'com.android.tools.build:gradle-experimental:0.9.3'
|
||||
classpath 'com.google.gms:google-services:3.0.0'
|
||||
classpath 'com.google.gms:google-services:3.1.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
|
Loading…
Reference in New Issue