我发现好多萌新拿了别人的项目准备参考,但是打开后跑不起来,调了半天也摸不清头脑
所以总结一下我的经验,希望能帮到大家
原因可能有以下几种
1.gradle版本不匹配
解决方法:(1)用studio新建一个项目,打开app目录下build.gradle文件把compileSdkVersion minSdkVersion targetSdkVersion改成一样的版本号dependencies引用的库也改成一样的版本(2)打开gradle目录下的gradle-wrapper.properties文件,把 distributionUrl改成一样(3)打开与app目录同级的build.gradle文件,把dependencies改成一样(4)sync(同步)
2.网络原因
有些库是Google提供的需要在与app目录同级的build.gradle文件中的buildscript结构的repositories结构下和allprojects结构的repositories结构下加google()
buildscript { repositories { google()
}
}
allprojects { repositories { google() jcenter() } }
还有一种是网络卡的情况,下载第三方类库失败,build下面会显示好多链接xxxxxx.jar,重新sync就可以了
3.动态权限原因
android M以上就需要动态申请权限了,别人的项目可能年代久远没有动态申请权限,需要我们动态申请权限,先在AndroidManifest.xml文件中声明权限然后动态获取
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
public class MainActivity extends AppCompatActivity {
private static final int NOT_NOTICE = 2;//如果勾选了不再询问
private AlertDialog alertDialog;
private AlertDialog mDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_permission);
myRequetPermission();
}
private void myRequetPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}else {
Toast.makeText(this,"您已经申请了权限!",Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 1) {
for (int i = 0; i < permissions.length; i++) {
if (grantResults[i] == PERMISSION_GRANTED) {//选择了“始终允许”
Toast.makeText(this, "" + "权限" + permissions[i] + "申请成功", Toast.LENGTH_SHORT).show();
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])){//用户选择了禁止不再询问
AlertDialog.Builder builder = new AlertDialog.Builder(PermissionActivity.this);
builder.setTitle("permission")
.setMessage("点击允许才可以使用我们的app哦")
.setPositiveButton("去允许", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (mDialog != null && mDialog.isShowing()) {
mDialog.dismiss();
}
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", getPackageName(), null);//注意就是"package",不用改成自己的包名
intent.setData(uri);
startActivityForResult(intent, NOT_NOTICE);
}
});
mDialog = builder.create();
mDialog.setCanceledOnTouchOutside(false);
mDialog.show();
}else {//选择禁止
AlertDialog.Builder builder = new AlertDialog.Builder(PermissionActivity.this);
builder.setTitle("permission")
.setMessage("点击允许才可以使用我们的app哦")
.setPositiveButton("去允许", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.dismiss();
}
ActivityCompat.requestPermissions(PermissionActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
});
alertDialog = builder.create();
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.show();
}
}
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==NOT_NOTICE){
myRequetPermission();//由于不知道是否选择了允许所以需要再次判断
}
}
}
PS:6.0权限的基本知识,以下是需要单独申请的权限,共分为9组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了
group1:android.permission-group.CONTACTS
permission:android.permission.WRITE_CONTACTS
permission:android.permission.GET_ACCOUNTS
permission:android.permission.READ_CONTACTS
group2:android.permission-group.PHONE
permission:android.permission.READ_CALL_LOG
permission:android.permission.READ_PHONE_STATE
permission:android.permission.CALL_PHONE
permission:android.permission.WRITE_CALL_LOG
permission:android.permission.USE_SIP
permission:android.permission.PROCESS_OUTGOING_CALLS
permission:com.android.voicemail.permission.ADD_VOICEMAIL
group3:android.permission-group.CALENDAR
permission:android.permission.READ_CALENDAR
permission:android.permission.WRITE_CALENDAR
group4:android.permission-group.CAMERA
permission:android.permission.CAMERA
group5:android.permission-group.SENSORS
permission:android.permission.BODY_SENSORS
group6:android.permission-group.LOCATION
permission:android.permission.ACCESS_FINE_LOCATION
permission:android.permission.ACCESS_COARSE_LOCATION
group7:android.permission-group.STORAGE
permission:android.permission.READ_EXTERNAL_STORAGE
permission:android.permission.WRITE_EXTERNAL_STORAGE
group8:android.permission-group.MICROPHONE
permission:android.permission.RECORD_AUDIO
group9:android.permission-group.SMS
permission:android.permission.READ_SMS
permission:android.permission.RECEIVE_WAP_PUSH
permission:android.permission.RECEIVE_MMS
permission:android.permission.RECEIVE_SMS
permission:android.permission.SEND_SMS
permission:android.permission.READ_CELL_BROADCASTS
普通权限,只需要在AndroidManifest.xml中申请
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
4.热更新问题
报错提示Unable to delete directory:\\...\build\xxxxxxxxx
原因是AndroidStudio默认支持热更新,只需在设置中关闭支持热更新的选项即可
Settings--Build,Execution,Deployment--Instant Run 关闭Enable Instant Run to hot swap code/resource changes on deploy(default enable)
5.有关相机的项目除了要动态申请权限(参考3)外还要解决android.os.FileUriExposedExecution错误
解决方法:Step1.在AndroidManifest.xml文件中添加如下代码:
<application
...
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
Step2.在res目录下新建一个xml文件夹,并且新建一个provider_paths的xml文件
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
注意external-path代表了不同的文件目录,一共有五种,下面是官网的说明:
<files-path name="name" path="path" />
Represents files in the files/ subdirectory of your app's internal storage area. This subdirectory is the same as the value returned byContext.getFilesDir(). 代表了Context.getFilesDir().
<cache-path name="name" path="path" />
Represents files in the cache subdirectory of your app's internal storage area. The root path of this subdirectory is the same as the value returned by getCacheDir().
<external-path name="name" path="path" />
Represents files in the root of the external storage area. The root path of this subdirectory is the same as the value returned byEnvironment.getExternalStorageDirectory().
<external-files-path name="name" path="path" />
Represents files in the root of your app's external storage area. The root path of this subdirectory is the same as the value returned byContext#getExternalFilesDir(String) Context.getExternalFilesDir(null).
<external-cache-path name="name" path="path" />
Represents files in the root of your app's external cache area. The root path of this subdirectory is the same as the value returned byContext.getExternalCacheDir().
Step3.修改代码
Uri photoURI = Uri.fromFile(createImageFile());
变成:
Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
暂时写这么多,想起来再继续更。大家遇到问题及时留言哦,我会经常翻评论的。