文章目录
1、Android10及以上 无法创建文件夹
解决方法:
-
修改gradie 中sdk版本号 29以下
-
使用Android规定的文件夹
-
添加android:requestLegacyExternalStorage=”true”到清单中。存储模型发生改变,这样是选择旧式存储模型,并且现有的外部存储代码将起作用。然后动态添加ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION 权限
2、多权限动态申请
public void checkPermission() {
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.CAMERA,
Manifest.permission.SET_ALARM,
Manifest.permission.CHANGE_NETWORK_STATE,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.ACCESS_WIFI_STATE,
Manifest.permission.READ_PHONE_STATE},
111);
}
//回调
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 111) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
Tools.showToast(MainActivity.this, "缺少权限(" + permissions[i] + ")");
return;
}
}
}
}
3、AndroidStudio 4.0以上Swicth提示
Resource IDs will be non-final in Android Gradle Plugin version 5.0, avoid using them in switch case statements
//4.0 以上提示 id可能会改变,所有不建议使用switch catch
Switch(view.getId()){
case R.id.btb:
//......
break;
case R.id.change:
//......
break;
...
...
}
//可以改用if else ,性能几乎没有影响
int id = view.getId();
if(id == R.id.btb){
//...........
}else if(id == R.id.change){
//...........
}...{
}...
4、Activity、Fragment之间的交互
1)Activity访问Fragment
如果Fragment是通过布局文件添加到activity中
//fragment是通过布局文件引入的
<fragment>
android:tag="fragment_bottom_tag"
android:id="@+id/fragment_bottom"
android:name="com.demo.BottomFragment"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"/>
</fragment>
//则有两种方式可以获取到fragment
BottomFragment fragment = (BottomFragment)getFragmentManager().findFragmentById(R.id.fragment_bottom): //通过id
BottomFragment fragment = (BottomFragment)getFragmentManager().findFragmentById("fragment_bottom_tag");//通过tag
//获取fragment中的某个控件
if(fragment != null){
fragment.getView().findViewById(R.id.text);
}
如果fragment 是通过new Fragment() 方式获取的,则直接通过变量名操作
<frameLayout
id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="50dp" />
//将Fragment添加到layout中
BottomFragment fragment = new BottomFragment();
getFragmentManager().beginTransaction()
.add(R.id.fragment_container,fragment).commit();
fragment.getView().findViewById(R.id.text);
2)Fragment访问Activity
方法一、通过getActivity()方法获取,但是这种方式不好
@Override
public void onActivityCreated(....){
//方法一(这种方式不好)在fragment中获取activity控件
CheckBox chkMarried = (CheckBox)getActivity().findViewById(R.id.chk_married);
button.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View view){
if(chkMarried.isChecked){}
}
});
//如果需要获取activity中的成员变量,只需要调用activity中的get()方法
}
方式二、通过创建回调函数来实现
Fragment与其附属着的activity之间的通信的最佳方式:
1、在发起事件的Fragment中定义一个接口,接口中声明你的方法
2、在onAttach方法中要求activity实现这个接口
3、在Activity中实现该方法
1、在fragmeng中定义接口
public interface OnNewItemAddListener{
public void newItemAdded(String content);
}
2、声明接口引用变量
private OnNewItemAddListener onNewItemAddListener;
3、在fragment的onAttach方法中要求activity实现这个方法
@Override
public void Attach(Activity activity){
super.onAttach(activity);
//要求该ftragment所附着的Activity必须完成这个方法的实现
try{
onNewItemAddListener = (OnNewItemAddListener) activity;
}catch(ClassCastException e){
}
}
4、在fragment中 需要的事件内 调用接口方法
onNewItemAddListenter.newItemAdded("");
5、在activity中必须实现接口
public class IndexActivity extends Activity implements OnNewItemAddListener{
。。。
。。。
@Override
public void newItemAdd(String content){
//操作fragment传过来的content
}
}
3)所有Fragment之间的通信
所有Fragment之间的通信,都应该通过他们所属的Activity来完成,不能是多个Fragment之间的直接通信、调用(尽管可以)
5、JAVA-startActivityResult 替代
用registerForActivityResult替代即可
ActivityResultLauncher launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
//此处是跳转的result回调方法
if (result.getData() != null && result.getResultCode() == Activity.RESULT_OK) {
Tools.showToast(context,"返回成功");
} else {
Tools.showToast(context,"返回失败");
}
}
});
注意:registerForActivityResult的初始化需要在onCreate中进行
调用
Intent intent = new Intent(context, Second.class);
launcher.launch(intent);
6、DataBinding 提示找不到类
在布局文间中引入类后:
<data>
<variable
name="idol"
type="com.kaiya.mvp.jetpacktest.DataBindingF.Idol" />
</data>
提示找不到 “com.kaiya.mvp.jetpacktest.dataBindingF.Idol”
原因:
Gradle4.6版本升级之前,包文件名首字母大小写都可以,升级以后文件名必须小写字母开头。所以需要将包文件名首字母改为小写
如下代码,将 “DataBindingF” 改为 “dataBindingF”
<data>
<variable
name="idol"
type="com.kaiya.mvp.jetpacktest.dataBindingF.Idol" />
</data>
7、DataBinding 提示 Cause: couldn’t make a guss for
在引入事件类时
<variable
name="eventHandle"
type="com.kaiya.mvp.jetpacktest.dataBindingF.eventHandleListener" />
提示 “使用dataBinding报错:Cause: couldn‘t make a guess for的解决办法”
原因:
是类名没遵循大驼峰命名法(首字母大写)导致的(eventHandleListener 首字母没有大写)
改成首字母大写就好了:
<variable
name="eventHandle"
//eventHandlerListener 首字母改为大写了 -> EventHandlerListener
type="com.kaiya.mvp.jetpacktest.dataBindingF.EventHandleListener" />
8、ViewBinding 与 DataBinding区别
https://developer.aliyun.com/article/938714