这是关于在请求权限时Android Marshmallow中引入的新运行时权限模型Manifest.permission.WRITE_EXTERNAL_STORAGE.
简而言之,我所遇到的是,如果我请求(和用户允许)Manifest.permission.WRITE_EXTERNAL_STORAGE权限,应用程序将无法从外部存储目录读取和写入,直到我销毁并重新启动应用程序.
这就是我正在做/经历的事情:
我的应用程序从以下状态开始:
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
Run Code Online (Sandbox Code Playgroud)
这是,我没有权限访问外部存储.
然后,我就像Google解释的那样请求Manifest.permission.WRITE_EXTERNAL_STORAGE的许可
private void requestWriteExternalStoragePermission() {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
new AlertDialog.Builder(this)
.setTitle("Inform and request")
.setMessage("You need to enable permissions, bla bla bla")
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
})
.show();
} else {
ActivityCompat.requestPermissions(MendeleyActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, RC_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
}
Run Code Online (Sandbox Code Playgroud)
一旦用户允许该权限,onRequestPermissionsResult就会被调用.
@Override …Run Code Online (Sandbox Code Playgroud) permissions android file-permissions runtime android-6.0-marshmallow
由于POODLE漏洞,我在Amazon AWS中托管的服务器不再支持SSLv3.
因此,我的Android应用程序对服务器执行的第一个HTTPS连接会在建立连接时导致错误.
Error reading server response: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
[....]
Caused by: javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x77d8ab68: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x7339ad74:0x00000000)
at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:448)
at com.android.okhttp.Connection.upgradeToTls(Connection.java:146)
at com.android.okhttp.Connection.connect(Connection.java:107)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
Run Code Online (Sandbox Code Playgroud)
该错误仅在第一个请求中发生.后续请求工作了一段时间.
为了解决这个问题,我试图从Android客户端接受的协议列表中删除SSL,并确保我只使用TLS.为此,我设置了一个自定义SSLSocketFactory,它从启用的协议和支持的密码套件列表中删除SSL.
/**
* SSLSocketFactory that wraps one existing SSLSocketFactory and delegetes into it …Run Code Online (Sandbox Code Playgroud) ssl android amazon-web-services sslsocketfactory poodle-attack
我正在使用Robolectric 2来测试我的Activity.这扩展了ActionBarActivity:
// This Activity uses one ActionBarCompat theme
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
Run Code Online (Sandbox Code Playgroud)
我的测试是:
@RunWith(RobolectricTestRunner.class)
public class MainActivityTest {
@Test
public void shouldBlaBlaBla() throws Exception {
Robolectric.buildActivity(MainActivity.class).create().get();
assert(...);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我告诉Robolectric创建Activity时,会抛出异常.
java.lang.NullPointerException
at java.util.regex.Matcher.getTextLength(Matcher.java:1234)
at java.util.regex.Matcher.reset(Matcher.java:308)
at java.util.regex.Matcher.<init>(Matcher.java:228)
at java.util.regex.Pattern.matcher(Pattern.java:1088)
at org.robolectric.res.ResName.<init>(ResName.java:25)
at org.robolectric.res.builder.RobolectricPackageManager.getActivityInfo(RobolectricPackageManager.java:70)
at android.support.v7.app.ActionBarActivityDelegate.getUiOptionsFromMetadata(ActionBarActivityDelegate.java:157)
at android.support.v7.app.ActionBarActivityDelegateICS.onCreate(ActionBarActivityDelegateICS.java:53)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:98)
at com.busuu.android.MainActivity.onCreate(MainActivity.java:31)
at android.app.Activity.performCreate(Activity.java:5008)
at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
at org.robolectric.util.ActivityController$1.run(ActivityController.java:117)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:256)
at org.robolectric.util.ActivityController.create(ActivityController.java:111)
at org.robolectric.util.ActivityController.create(ActivityController.java:124)
at com.busuu.android.MainActivityTest.mainActivityShouldProvideASlidingMenu(MainActivityTest.java:16)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
at …Run Code Online (Sandbox Code Playgroud) 我正在使用 Android Jetpack 导航组件。我有一个带有 id 的嵌套导航图,比如说嵌套图R.id.nested_graph
的第一个Fragment接收一个参数。
<navigation
android:id="@+id/nested_graph"
android:label="Nested Graph"
app:startDestination="@id/firstFragment">
<fragment
android:id="@+id/firstFragment"
android:name="...."
android:label="....">
<argument
android:name="item_id"
app:argType="integer" />
</fragment>
[...]
</navigation>
Run Code Online (Sandbox Code Playgroud)
如何使用安全 args将参数传递给嵌套图?
目前,我需要在包中手动传递参数,使用直接接收嵌套图的 id 的 API:
val args = Bundle()
args.putInt("item_id", itemId)
navController.navigate(R.id.nested_graph, args)
Run Code Online (Sandbox Code Playgroud)
我想使用安全参数,并执行以下操作:
val directions = OrigininFragmentDirections.nestedGraph(itemId)
navController.navigate(directions)
Run Code Online (Sandbox Code Playgroud)
但是在尝试时,我在构建时收到以下错误:
Too many arguments for public final fun nestedGraph(): NavDirections defined
Run Code Online (Sandbox Code Playgroud)
问题是导航图预处理正在生成工厂方法来创建没有签名中所需参数的NavDirections对象。
嵌套图的声明如下所示:
android android-navigation android-jetpack-navigation android-navigation-graph
我正在使用MVP构建一个Android应用程序,我对此模式有一个疑问.
假设我有一个用于创建新人的屏幕.此屏幕将显示一个EditText用于插入名称,另一个用于ImageView显示所选照片图片等.这将导致一个View界面,由Fragment.它将与一个Presenter接口合作,由另一个类实现.
精细.
现在我有另一个功能:用于编辑现有人的屏幕.碰巧,View此功能与创建新人的功能相同.但是,Presenter情况有所不同.它将从db中加载现有人员以使用当前数据预先填充视图开始,单击"save"时对数据库的操作将是更新而不是插入.
因此,我认为这是MVP的一个示例,其中一个View与演示者的不同实现一起工作以实现不同的用例.
你认为这是一个正确的假设,或者你觉得不同的特点应该有不同的View和Presenter接口?
另外,如果你有一个共同的View和不同的Presenters,将View是共同的实现,还是会导致两个类实现相同的接口?在实践中,我看到两个选项.
只有一个Fragment实施View.根据用户是要创建新人还是更新现有人,Fragment应该接收并使用不同的Presenter.
有两个Fragment.每个人都会实例化一个不同的Presenter.使用组合或继承来避免在两个片段之间复制代码.
在这些情况下,您认为更好的做法是什么?
谢谢.
我希望能够在Android Studio中进行单元测试和仪器测试,并在其中使用Mockito.
我在Android Studio 0.8中使用新方法进行测试.这是:
如何在我的测试中编写代码,这些代码依赖于仅用于测试的库,例如mockito或hamcrest?
我想在编译和运行测试时包含这些库,但要避免将它们导出到已发布的.apk.
在https://code.google.com/p/mockito/wiki/DeclaringMockitoDependency中,我读过我应该将依赖项添加为:
dependencies {
....
testCompile "org.mockito:mockito-core:1.9.5"
}
Run Code Online (Sandbox Code Playgroud)
但是当我跑步时我得到:
构建脚本错误,找不到支持的Gradle DSL方法:'testCompile()'!
虽然我不确定它是否相关,但我使用的gradle构建文件是:
apply plugin: 'android'
dependencies {
compile fileTree(dir: 'libs', include: '*.jar')
compile project(':android-sdk')
testCompile "org.mockito:mockito-core:1.9.5"
}
android {
compileSdkVersion 19
buildToolsVersion "20.0.0"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
renderscript.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
} …Run Code Online (Sandbox Code Playgroud) 说我们有:
public method(Integer s) {
....
}
Run Code Online (Sandbox Code Playgroud)
Java承认该方法的调用:
method(7);
Run Code Online (Sandbox Code Playgroud)
要么
int i = 7;
method(i);
Run Code Online (Sandbox Code Playgroud)
这样做时,JVM是否会创建一个新的Integer?如果我使用相同的int多次调用该方法,我是否创建了几个整数,或者使用了包装对象的"缓存"版本?
谢谢.
android ×6
hamcrest ×1
java ×1
mockito ×1
mvp ×1
object ×1
permissions ×1
presenter ×1
robolectric ×1
runtime ×1
ssl ×1
ui-patterns ×1
wrapper ×1