ios如何快速轉型安卓開發-專題3
1.Fragment
可以嵌入活動當中的UI片段。
1.碎片的通訊
FragmentManager提供一個finViewById,專門從佈局檔案中獲取碎片的例項
2.碎片的生命週期
1.狀態
(1)執行狀態:可見
(2)暫停狀態:被覆蓋但部分可見
(3)停止狀態:完全不可見
(4)銷燬狀態:被移除
2.回撥
(1)onAttach()。碎片和活動建立關聯。
(2)onCreateView()。碎片建立檢視時呼叫。
(3)onActivityCreated()。確保與碎片相關聯的活動一定已經建立完畢的時候呼叫。
(4)onDestory()。當與碎片關聯的檢視被移除的時候呼叫。
(5)onDetach()。當碎片與活動解除關聯的時候呼叫。
3.動態載入佈局
使用限定符匹配對應的平板和手機情況。
4.系統通知
點選檢視程式碼
package com.example.notificationtest; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.NotificationCompat; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Build; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { final String CHANNEL_ID = "channel_id_1"; final String CHANNEL_NAME = "channel_name_1"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button sendNotice = (Button) findViewById(R.id.send_notice); sendNotice.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.O) @Override public void onClick(View v) { Context context = getBaseContext(); Intent intent = new Intent(MainActivity.this,MainActivity.class); PendingIntent pi = PendingIntent.getActivity(MainActivity.this,0,intent,0); NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); //Notification notification = new Notification(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR_0_1) { NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID,CHANNEL_NAME,NotificationManager.IMPORTANCE_HIGH); manager.createNotificationChannel(notificationChannel); } Notification notification; notification = new NotificationCompat.Builder(MainActivity.this,CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setPriority(NotificationCompat.PRIORITY_MAX) .setContentTitle("通知標題") .setAutoCancel(true) .setContentText("This is a notification This is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notificationThis is a notification") .setContentIntent(pi) .setVibrate(new long[]{0,1000,1000,1000}) .setWhen(System.currentTimeMillis()) .build(); manager.notify(0,notification); } }); } } <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.notificationtest"> <uses-permission android:name="android.permission.VIBRATE" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.NotificationTest"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
2.Service
1.服務的生命週期
生命週期回撥方法:
(1)onCreate()
(2)onStartCommand()
(3)onBind()
(4)onDestory
呼叫startService()方法後,對應服務就會啟動,並回調onStartCommand()方法,服務沒有建立,onCreate()就會先於onStartCommand()方法執行,呼叫stopService,unBindService方法,執行onDestory方法。
2.前後臺服務
點選檢視程式碼
package com.example.servicetest;
import android.app.IntentService;
import android.content.Intent;
import android.util.Log;
import androidx.annotation.Nullable;
public class MyIntentService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public MyIntentService(String name) {
super(name);
}
public MyIntentService(){
super(null);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
Log.d("MyIntentService", "Thread id is" + Thread.currentThread().getId());
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyIntentService", "onDestroy executed");
}
}
package com.example.servicetest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
public class MyService extends Service {
public MyService() {
}
private DownloadBinder mBinder = new DownloadBinder();
class DownloadBinder extends Binder {
public void startDownload() {
Log.d("MyService", "startDownload executed");
}
public int getProgress() {
Log.d("MyService", "getProgress executed");
return 0;
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onCreate() {
super.onCreate();
Log.d("MyService","onCreate executed");
Intent intent = new Intent(MyService.this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0, intent, 0);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel("channel_id","channel_name",NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(notificationChannel);
Notification notification = new NotificationCompat.Builder(MyService.this,"channel_id")
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher))
.setContentIntent(pi)
.build();
startForeground(1, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("MyService","onStartCommand executed");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d("MyService","onDestroy executed");
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
return mBinder;
}
}
package com.example.servicetest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private MyService.DownloadBinder mDownloadBinder;
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mDownloadBinder = (MyService.DownloadBinder) service;
mDownloadBinder.startDownload();;
mDownloadBinder.getProgress();
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startService = (Button) findViewById(R.id.startService);
Button stopService = (Button) findViewById(R.id.stopService);
Button bindService = (Button) findViewById(R.id.bindService);
Button unbindService = (Button) findViewById(R.id.unbindService);
Button startIntentService = (Button) findViewById(R.id.startIntentService);
startService.setOnClickListener(this);
stopService.setOnClickListener(this);
bindService.setOnClickListener(this);
unbindService.setOnClickListener(this);
startIntentService.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.startService:
Intent startIntent = new Intent(this,MyService.class);
startService(startIntent);
break;
case R.id.stopService:
Intent stopIntent = new Intent(this, MyService.class);
stopService(stopIntent);
break;
case R.id.bindService:
Intent bindIntent = new Intent(this, MyService.class);
bindService(bindIntent, mConnection, BIND_AUTO_CREATE);
break;
case R.id.unbindService:
unbindService(mConnection);
break;
case R.id.startIntentService:
Log.d("MainActivity","Thread id is" + Thread.currentThread().getId());
Intent intentService = new Intent(this, MyIntentService.class);
startService(intentService);
break;
default:
break;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.servicetest">
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.ServiceTest">
<service
android:name=".MyService"
android:enabled="true"
android:exported="true"></service>
<service android:name=".MyIntentService" />
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
3.多執行緒
1.非同步訊息處理機制
非同步訊息處理:由四個部分組成,Message、Hanlder、MessageQueue、Looper。
(1)Message:執行緒之間傳遞訊息,用於在不同執行緒之間交換資料。
(2)Handler:用於傳送和處理訊息,sendMessgae(),經過一系列的處理之後,傳遞到HandleMessgae中。
(3)MessageQueue:用於存放所有通過Handler傳送的訊息,每個執行緒只會有一個MessageQueue物件。
(4)Looper:每個執行緒中的MessageQueue的關機,呼叫Looper中的loop()方法後,會進入到一個無限迴圈當中,發現MessageQueue中存在一條訊息,就會將其取出,傳遞到HanleMessage方法中。每個執行緒中也只會有一個looper物件。
2.AsyncTask使用
重新其中方法可完成對應的任務排程
(1)onProExecute():在後臺任務開始執行前呼叫,用於進行介面上的初始化操作。
(2)doInBackground(Params...):方法中所有程式碼都會在子執行緒中執行,不可以進行UI的操作
(3)onProgressUpdate(Progress...):後臺呼叫了publishProgress(Progress...)方法後,此方法就會呼叫,返回的資料作為引數傳遞,可以進行Ui操作。
(4)onPostExecute(Result):後臺任務執行完畢之後,並執行return 返回時,呼叫此方法,返回資料作為引數傳遞到此方法中,可以利用返回資料做UI操作。
4.接入三方SDK實現and ServiceTest
點選檢視程式碼
package com.example.servicebestpratice;
public interface DownloadListener {
void onProgress(int progress);
void onSuccess();
void onFailed();
void onPaused();
void onCancled();
}
package com.example.servicebestpratice;
import java.io.File;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.IBinder;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
public class DownloadService extends Service {
private DownloadTask mDownloadTask;
private String downloadUrl;
private NotificationManager mManager;
private DownloadListener mListener = new DownloadListener() {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onProgress(int progress) {
getNotificationManager().notify(1,getNotification("Downloading...",progress));
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onSuccess() {
mDownloadTask = null;
stopForeground(true);
getNotificationManager().notify(1,getNotification("Download Success", -1));
Toast.makeText(DownloadService.this, "Download Success", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailed() {
mDownloadTask = null;
Toast.makeText(DownloadService.this, "Download Failed", Toast.LENGTH_SHORT).show();
}
@Override
public void onPaused() {
mDownloadTask = null;
Toast.makeText(DownloadService.this, "Download Paused", Toast.LENGTH_SHORT).show();
}
@Override
public void onCancled() {
mDownloadTask = null;
Toast.makeText(DownloadService.this, "Download Cancled", Toast.LENGTH_SHORT).show();
}
};
public DownloadService() {
}
private DownloadBinder mBinder = new DownloadBinder();
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
class DownloadBinder extends Binder {
@RequiresApi(api = Build.VERSION_CODES.O)
public void startDownload(String url) {
if (mDownloadTask == null) {
downloadUrl = url;
mDownloadTask = new DownloadTask(mListener);
mDownloadTask.execute(downloadUrl);
mManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel("channelId","channelName",NotificationManager.IMPORTANCE_HIGH);
mManager.createNotificationChannel(notificationChannel);
startForeground(1,getNotification("Download...",0));
Toast.makeText(DownloadService.this, "Downloading...",Toast.LENGTH_SHORT).show();
}
}
public void pauseDownload() {
if (mDownloadTask != null) {
mDownloadTask.pauseDownload();
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
public void cancelDownload() {
if (mDownloadTask != null) {
mDownloadTask.cancelDownload();
} else {
if (downloadUrl != null) {
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
File file = new File(directory + fileName);
if (file.exists()) {
file.delete();
}
getNotificationManager().cancel(1);
stopForeground(true);
Toast.makeText(DownloadService.this, "Canceled", Toast.LENGTH_SHORT).show();
}
}
}
}
@RequiresApi(api = Build.VERSION_CODES.O)
private NotificationManager getNotificationManager() {
return mManager;
}
private Notification getNotification(String title, int progress) {
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,"channelId");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher));
builder.setContentIntent(pi);
builder.setContentTitle(title);
if (progress > 0) {
builder.setContentText(progress + "%");
builder.setProgress(100,progress,false);
}
return builder.build();
}
}
package com.example.servicebestpratice;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import android.os.AsyncTask;
import android.os.Environment;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class DownloadTask extends AsyncTask<String, Integer, Integer> {
public static final int TYPE_SUCCESS = 0;
public static final int TYPE_FAILED = 1;
public static final int TYPE_PAUSED = 2;
public static final int TYPE_CANCELED = 3;
private DownloadListener mListener;
private boolean isCanceled = false;
private boolean isPaused = false;
private int lastProgress;
public DownloadTask(DownloadListener listener) {
this.mListener = listener;
}
@Override
protected Integer doInBackground(String... strings) {
InputStream is = null;
RandomAccessFile savedFile = null;
File file = null;
try {
long downloadedLength = 0;
String downloadUrl = strings[0];
String fileName = downloadUrl.substring(downloadUrl.lastIndexOf("/"));
String directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
file = new File(directory + fileName);
if (file.exists()) {
downloadedLength = file.length();
}
long contentLength = getContentLength(downloadUrl);
if (contentLength == 0) {
return TYPE_FAILED;
} else if (contentLength == downloadedLength) {
return TYPE_SUCCESS;
}
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.addHeader("RANGE","bytes=" + downloadedLength + "-")
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null) {
is = response.body().byteStream();
savedFile = new RandomAccessFile(file, "rw");
savedFile.seek(downloadedLength);
byte[] b = new byte[1024];
int total = 0;
int len;
while ((len = is.read(b))!=-1) {
if (isCanceled) {
return TYPE_CANCELED;
} else if (isPaused) {
return TYPE_PAUSED;
} else {
total += len;
savedFile.write(b,0,len);
int progress = (int)((total+downloadedLength) * 100 / contentLength);
publishProgress(progress);
}
}
response.close();
return TYPE_SUCCESS;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (savedFile != null) {
savedFile.close();
}
if (isCanceled && file != null) {
file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
int progress = values[0];
if (progress > lastProgress) {
mListener.onProgress(progress);
lastProgress = progress;
}
}
@Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
switch (integer) {
case TYPE_CANCELED:
mListener.onCancled();
break;
case TYPE_SUCCESS:
mListener.onSuccess();
break;
case TYPE_PAUSED:
mListener.onPaused();
break;
case TYPE_FAILED:
mListener.onFailed();
default:
break;
}
}
private long getContentLength(String downloadUrl) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(downloadUrl)
.build();
Response response = client.newCall(request).execute();
if (response != null && response.isSuccessful()) {
long contentLength = response.body().contentLength();
response.close();
return contentLength;
}
return 0;
}
public void pauseDownload() {
isPaused = true;
}
public void cancelDownload() {
isCanceled = true;
}
}
package com.example.servicebestpratice;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.baidu.location.BDAbstractLocationListener;
import com.baidu.location.BDLocation;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private DownloadService.DownloadBinder mDownloadBinder;
private LocationClient mLocationClient;
private MyLocationListener mListener = new MyLocationListener();
private TextView positionText;
private final ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mDownloadBinder = (DownloadService.DownloadBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
public class MyLocationListener extends BDAbstractLocationListener {
@Override
public void onReceiveLocation(BDLocation bdLocation) {
double latitude = bdLocation.getLatitude();
double longitude = bdLocation.getLongitude();
float radius = bdLocation.getRadius();
String coorType = bdLocation.getCoorType();
int errorCode = bdLocation.getLocType();
positionText.setText(latitude + " ++ " +longitude + " ++ " +radius + " ++ " +coorType + " ++ ");
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLocationClient = new LocationClient(getApplicationContext());
mLocationClient.registerLocationListener(mListener);
LocationClientOption option = new LocationClientOption();
option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
option.setScanSpan(1000);
mLocationClient.setLocOption(option);
mLocationClient.start();
Button startDownload = (Button) findViewById(R.id.start_download);
Button pauseDownload = (Button) findViewById(R.id.pause_download);
Button cancelDownload = (Button) findViewById(R.id.cancel_download);
positionText = (TextView) findViewById(R.id.position_text_view);
startDownload.setOnClickListener(this);
pauseDownload.setOnClickListener(this);
cancelDownload.setOnClickListener(this);
Intent intent = new Intent(this, DownloadService.class);
startService(intent);
bindService(intent, mConnection, BIND_AUTO_CREATE);
if (ContextCompat
.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}
@SuppressLint("NonConstantResourceId")
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onClick(View v) {
if (mDownloadBinder == null) {
return;
}
switch (v.getId()) {
case R.id.start_download:
String url = "https://raw.githubusercontent.com/guolindev/eclipse/master/eclipse-inst-win64.exe";
mDownloadBinder.startDownload(url);
break;
case R.id.pause_download:
mDownloadBinder.pauseDownload();
break;
case R.id.cancel_download:
mDownloadBinder.cancelDownload();
break;
default:
break;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
if (requestCode == 1) {
if (grantResults.length > 0 && grantResults[0] != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "failed", Toast.LENGTH_SHORT).show();
finish();
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mConnection);
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/start_download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start Downlaod" />
<Button
android:id="@+id/pause_download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pause Downlaod" />
<Button
android:id="@+id/cancel_download"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Cancel Downlaod" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/position_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
plugins {
id 'com.android.application'
}
android {
compileSdk 31
defaultConfig {
ndk {
// 設定支援的SO庫架構(開發者可以根據需要,選擇一個或多個平臺的so)
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
}
applicationId "com.example.servicebestpratice"
minSdk 21
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', includes: ['*.jar'])
implementation("com.squareup.okhttp3:okhttp:4.2.0")
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.4.0'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Util:7.4.0'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.4.0'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Location:9.1.8'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}