Update android sdk to v23

Deal with Android 6 permission system
Update gradle version
This commit is contained in:
Synced Synapse 2016-05-25 17:18:25 +01:00
parent 3e0d3a7e36
commit 6dcf412140
10 changed files with 109 additions and 17 deletions

View File

@ -11,13 +11,13 @@ def getVersionName = { ->
android { android {
compileSdkVersion 22 compileSdkVersion 23
buildToolsVersion "22.0.1" buildToolsVersion "23.0.3"
defaultConfig { defaultConfig {
applicationId "org.xbmc.kore" applicationId "org.xbmc.kore"
minSdkVersion 15 minSdkVersion 15
targetSdkVersion 22 targetSdkVersion 23
versionCode 13 versionCode 13
versionName = getVersionName() versionName = getVersionName()
} }
@ -80,9 +80,10 @@ android {
} }
dependencies { dependencies {
compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:support-v4:23.4.0'
compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:cardview-v7:22.2.0' compile 'com.android.support:cardview-v7:23.4.0'
compile 'com.android.support:support-v13:23.4.0'
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.2' compile 'com.fasterxml.jackson.core:jackson-databind:2.5.2'
compile 'com.jakewharton:butterknife:6.1.0' compile 'com.jakewharton:butterknife:6.1.0'

View File

@ -7,8 +7,10 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.VIBRATE"/> <uses-permission android:name="android.permission.VIBRATE"/>
<!-- Dangerous permissions -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application <application

View File

@ -15,10 +15,13 @@
*/ */
package org.xbmc.kore.service; package org.xbmc.kore.service;
import android.Manifest;
import android.app.Service; import android.app.Service;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.content.ContextCompat;
import org.xbmc.kore.Settings; import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostConnectionObserver; import org.xbmc.kore.host.HostConnectionObserver;
@ -102,12 +105,15 @@ public class ConnectionObserversManagerService extends Service
mConnectionObservers.add(new NotificationObserver(this)); mConnectionObservers.add(new NotificationObserver(this));
} }
// Check whether we should react to phone state changes // Check whether we should react to phone state changes and wether
// we have permissions to do so
boolean shouldPause = PreferenceManager boolean shouldPause = PreferenceManager
.getDefaultSharedPreferences(this) .getDefaultSharedPreferences(this)
.getBoolean(Settings.KEY_PREF_USE_HARDWARE_VOLUME_KEYS, .getBoolean(Settings.KEY_PREF_PAUSE_DURING_CALLS,
Settings.DEFAULT_PREF_USE_HARDWARE_VOLUME_KEYS); Settings.DEFAULT_PREF_PAUSE_DURING_CALLS);
if (shouldPause) { boolean hasPhonePermission =
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
if (shouldPause && hasPhonePermission) {
mConnectionObservers.add(new PauseCallObserver(this)); mConnectionObservers.add(new PauseCallObserver(this));
} }
} }

View File

@ -16,11 +16,16 @@
package org.xbmc.kore.ui; package org.xbmc.kore.ui;
import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.content.ServiceConnection; import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout; import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@ -40,6 +45,7 @@ import org.xbmc.kore.service.library.LibrarySyncService;
import org.xbmc.kore.service.library.SyncUtils; import org.xbmc.kore.service.library.SyncUtils;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.Optional; import butterknife.Optional;
@ -174,6 +180,15 @@ abstract public class AbstractDetailsFragment extends Fragment
@Optional @Optional
@OnClick(R.id.download) @OnClick(R.id.download)
public void onDownloadClicked(View v) { public void onDownloadClicked(View v) {
boolean hasStoragePermission =
ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
if (!hasStoragePermission) {
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
Utils.PERMISSION_REQUEST_WRITE_STORAGE);
return;
}
if (Settings.allowedDownloadNetworkTypes(getActivity()) != 0) { if (Settings.allowedDownloadNetworkTypes(getActivity()) != 0) {
onDownload(); onDownload();
} else { } else {
@ -181,6 +196,23 @@ abstract public class AbstractDetailsFragment extends Fragment
} }
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case Utils.PERMISSION_REQUEST_WRITE_STORAGE:
// If request is cancelled, the result arrays are empty.
if ((grantResults.length > 0) &&
(grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
onDownloadClicked(null);
} else {
Toast.makeText(getActivity(), R.string.write_storage_permission_denied, Toast.LENGTH_SHORT)
.show();
}
break;
}
}
protected void startSync(boolean silentRefresh) { protected void startSync(boolean silentRefresh) {
this.silentRefresh = silentRefresh; this.silentRefresh = silentRefresh;
LogUtils.LOGD(TAG, "Starting syc. Silent? " + silentRefresh); LogUtils.LOGD(TAG, "Starting syc. Silent? " + silentRefresh);

View File

@ -18,7 +18,7 @@ package org.xbmc.kore.ui;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v7.app.ActionBarActivity; import android.support.v7.app.AppCompatActivity;
import org.xbmc.kore.Settings; import org.xbmc.kore.Settings;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
@ -26,7 +26,7 @@ import org.xbmc.kore.utils.UIUtils;
/** /**
* Base activity, where common behaviour is implemented * Base activity, where common behaviour is implemented
*/ */
public class BaseActivity extends ActionBarActivity { public class BaseActivity extends AppCompatActivity {
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {

View File

@ -15,6 +15,7 @@
*/ */
package org.xbmc.kore.ui; package org.xbmc.kore.ui;
import android.Manifest;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
@ -23,7 +24,12 @@ import android.preference.ListPreference;
import android.preference.MultiSelectListPreference; import android.preference.MultiSelectListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.TwoStatePreference;
import android.support.annotation.NonNull;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.TaskStackBuilder; import android.support.v4.app.TaskStackBuilder;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;
import org.xbmc.kore.R; import org.xbmc.kore.R;
import org.xbmc.kore.Settings; import org.xbmc.kore.Settings;
@ -31,6 +37,7 @@ import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.service.ConnectionObserversManagerService; import org.xbmc.kore.service.ConnectionObserversManagerService;
import org.xbmc.kore.utils.LogUtils; import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils; import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -73,6 +80,13 @@ public class SettingsFragment extends PreferenceFragment
} }
} }
// Check permission for phone state and set preference accordingly
if (!hasPhonePermission()) {
TwoStatePreference pauseCallPreference =
(TwoStatePreference)findPreference(Settings.KEY_PREF_PAUSE_DURING_CALLS);
pauseCallPreference.setChecked(false);
}
setupPreferences(); setupPreferences();
} }
@ -107,7 +121,17 @@ public class SettingsFragment extends PreferenceFragment
.startActivities(); .startActivities();
} }
// If one of the settings that use the observer service are modified, restart it // If the pause during call is selected, make sure we have permission to read phone state
if (key.equals(Settings.KEY_PREF_PAUSE_DURING_CALLS) &&
(sharedPreferences.getBoolean(Settings.KEY_PREF_PAUSE_DURING_CALLS, Settings.DEFAULT_PREF_PAUSE_DURING_CALLS))) {
if (!hasPhonePermission()) {
FragmentCompat.requestPermissions(this,
new String[] {Manifest.permission.READ_PHONE_STATE},
Utils.PERMISSION_REQUEST_READ_PHONE_STATE);
}
}
// If one of the settings that use the observer service are modified, restart it
if (key.equals(Settings.KEY_PREF_SHOW_NOTIFICATION) || key.equals(Settings.KEY_PREF_PAUSE_DURING_CALLS)) { if (key.equals(Settings.KEY_PREF_SHOW_NOTIFICATION) || key.equals(Settings.KEY_PREF_PAUSE_DURING_CALLS)) {
LogUtils.LOGD(TAG, "Stoping connection observer service"); LogUtils.LOGD(TAG, "Stoping connection observer service");
Intent intent = new Intent(getActivity(), ConnectionObserversManagerService.class); Intent intent = new Intent(getActivity(), ConnectionObserversManagerService.class);
@ -116,6 +140,27 @@ public class SettingsFragment extends PreferenceFragment
} }
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case Utils.PERMISSION_REQUEST_READ_PHONE_STATE:
// If request is cancelled, the result arrays are empty.
if ((grantResults.length == 0) ||
(grantResults[0] != PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(getActivity(), R.string.read_phone_state_permission_denied, Toast.LENGTH_SHORT)
.show();
TwoStatePreference pauseCallPreference =
(TwoStatePreference)findPreference(Settings.KEY_PREF_PAUSE_DURING_CALLS);
pauseCallPreference.setChecked(false);
}
break;
}
}
private boolean hasPhonePermission() {
return ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
}
/** /**
* Sets up the preferences state and summaries * Sets up the preferences state and summaries
*/ */

View File

@ -32,6 +32,9 @@ import java.util.List;
* */ * */
public class Utils { public class Utils {
public static final int PERMISSION_REQUEST_WRITE_STORAGE = 0,
PERMISSION_REQUEST_READ_PHONE_STATE = 1;
/** /**
* Returns whether the SDK is the Jellybean release or later. * Returns whether the SDK is the Jellybean release or later.
*/ */

View File

@ -383,4 +383,7 @@
<string name="download_network_types_summary">Allowed network types for media downloads</string> <string name="download_network_types_summary">Allowed network types for media downloads</string>
<string name="songs">Songs</string> <string name="songs">Songs</string>
<string name="read_phone_state_permission_denied">Permission denied. Won\'t be able to pause playback during calls.</string>
<string name="write_storage_permission_denied">Permission denied. Won\'t be able to download files.</string>
</resources> </resources>

View File

@ -5,7 +5,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:1.5.0' classpath 'com.android.tools.build:gradle:2.1.0'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

View File

@ -1,6 +1,6 @@
#Wed Apr 10 15:27:10 PDT 2013 #Tue May 24 19:19:59 WEST 2016
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip