How ios rapidly transforms Android Development - Topic 3

1.Fragment

You can embed UI fragments in activities.

1. Debris communication

The fragment manager provides a finViewById, which is used to obtain instances of fragments from layout files

2. Life cycle of debris

1. Status
(1) Operating status: visible
(2) Pause status: covered but partially visible
(3) Stop status: completely invisible
(4) Destruction status: removed
2. Callback
(1)onAttach(). Debris is associated with activity.
(2)onCreateView(). Called when the fragment creates a view.
(3)onActivityCreated(). Ensure that the activity associated with the fragment must be called when it has been created.
(4)onDestory(). Called when the view associated with the fragment is removed.
(5)onDetach(). Called when the fragment is disassociated from the activity.

3. Dynamic loading layout

Use the qualifier to match the corresponding tablet and mobile phone.

4. System notification
Click to view the code
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("Notice title")
            .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>
Note: for higher versions of Android, you need to pass in the channel and set the corresponding channeld to pop up the corresponding system notification. android:requestLegacyExternalStorage="true" this function needs to be set during external storage operations

2.Service

1. Service life cycle

Lifecycle callback method:
(1)onCreate()
(2)onStartCommand()
(3)onBind()
(4)onDestory
After calling the startService() method, the corresponding service will start and call back the onStartCommand() method. If the service is not created, onCreate() will execute before the onStartCommand() method. Call stopService and unBindService methods to execute the onDestory method.

2. Front and rear desk service
Click to view the code
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. Multithreading

1. Asynchronous message processing mechanism

Asynchronous Message processing: it consists of four parts: Message, Hanlder, MessageQueue and Looper.
(1) Message: passing messages between threads, used to exchange data between different threads.
(2) Handler: used to send and process messages. sendMessgae() is passed to handlemessae after a series of processing.
(3) MessageQueue: used to store all messages sent through the Handler. Each thread will only have one MessageQueue object.
(4) Looper: when the MessageQueue in each thread is shut down, after calling the loop () method in looper, it will enter an infinite loop. If a message is found in the MessageQueue, it will be taken out and delivered to the HanleMessage method. There will also be only one looper object per thread.

2.AsyncTask usage

The corresponding task scheduling can be completed by re using the method
(1) onProExecute (): before the background task starts executing, it is called for initialization operation on the interface.
(2) doInBackground(Params...): all code in the method will be executed in the sub thread, and UI operations are not allowed
(3) onProgressUpdate(Progress...): this method will be called after the publishProgress(Progress...) method is called in the background. The returned data is passed as a parameter for Ui operation.
(4) onPostExecute(Result): after the background task is executed and returns, this method is called. The returned data is passed to this method as a parameter. You can use the returned data for UI operations.

4. Access the third-party SDK to implement and ServiceTest

Click to view the code
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 {
            // Set the supported so Library Architecture (developers can select so of one or more platforms as needed)
            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'
}

Added by sarathi on Wed, 10 Nov 2021 00:07:38 +0200