在裝置上產生 2 個相同的啟動圖示

情境:
安裝 App 後在裝置上產生 2 個該 App 的啟動圖示

原因:
通常是在 AndroidManifest.xml 中的 Activity,同時存在 2 個如下的 intent-filter 內容
      <intent-filter>  
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>

如下面的 SplashActivity 和 MainActivity 都有相同的 intent-filter
...    
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="2 launcher icon"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">

<activity android:name=".splash.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

</application>

 

解法:
移除其中一個相同的 intent-filter

Orignal From: 在裝置上產生 2 個相同的啟動圖示

Android Studio 在專案中引用 AAR

使用 Android Studio 並在專案中引用 AAR,需要 2 個步驟

1.把要使用的 AAR 檔拷貝到 app/libs 目錄,完成後如下圖


2.右鍵點擊專案 -> Open Module Settings

2-1.選擇左方的 Modules 的 app -> 點擊左上方的 + 號,如下圖
2-2. 在 Create New Module 視窗選擇 Import .JAR/.AAR Package -> 點擊 next


2-3.在 import Module from Library 視窗的 File Name: 選擇第1步驟的 AAR 檔案位置 -> 點擊 OK -> Subproject name: 不必修改 -> 點擊 Finish -> Gradle 會自動更新,更新完成後點擊 OK

2-4.右鍵點擊專案 -> Open Module Settings -> 左方 Modules 選擇 app -> 點擊右上方 Dependencies -> 點擊最右上方的 + 號 -> 選擇 3 Module dependency


2-5.在 Choose Modules 視窗選擇 CommonTool-debug -> 點擊 OK -> 在 Project Structure 視窗點擊 OK -> 完成

 

Orignal From: Android Studio 在專案中引用 AAR

在Activity中判斷滑動手勢

在 Activity 判斷滑動手勢主要是透過 View.OnTouchListener 和 GestureDetector.OnGestureListener

透過讓 Activity 繼承 GestureDetector.OnGestureListener 並實作其中的 onFling 方法,在 onFling 方法中判斷第1個按下點的 X 座標和第2個按下點的 X 座標是否超過標準值來決定是否為滑動手勢。

經過測試即使是嵌入在 Activity 的 ListView 也可以成功偵測滑動手勢。
import android.support.constraint.ConstraintLayout;  
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;

public class FlingGestureExampleMainActivity extends AppCompatActivity implements View.OnTouchListener,
GestureDetector.OnGestureListener{

private static final String TAG = FlingGestureExampleMainActivity.class.getSimpleName();

//main ui
private ConstraintLayout mBasicLayout;
private GestureDetector mGesetureDetector;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fling_gesture_example_main_activity);

mBasicLayout = findViewById(R.id.basic_layout_activity);
mBasicLayout.setOnTouchListener(this);
mBasicLayout.setLongClickable(true);
mGesetureDetector = new GestureDetector((GestureDetector.OnGestureListener) this);
}

@Override
public boolean onDown(MotionEvent e) {
return false;
}

@Override
public void onShowPress(MotionEvent e) {

}

@Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
}

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
return false;
}

@Override
public void onLongPress(MotionEvent e) {

}

@Override
public boolean onFling(MotionEvent firstMotion, MotionEvent secondMotion, float velocityX, float velocityY) {
final int FLING_MIN_DISTANCE = 100;
final int FLING_MIN_VELOCITY = 200;

boolean isFlingToLeft = firstMotion.getX() - secondMotion.getX() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY;
if (isFlingToLeft) {
Log.d(TAG, "to left");
}
boolean isFlingToRight = firstMotion.getX() - secondMotion.getX() < FLING_MIN_DISTANCE && Math.abs(velocityX) < FLING_MIN_VELOCITY;
if (isFlingToRight) {
Log.d(TAG, "to right");
}
return false;
}

@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
return mGesetureDetector.onTouchEvent(motionEvent);
}
}

主要的重點為讓 Activity實作 onDown, onShowPress, on SingleTapUp, onScroll, onLongPress, onFling, onTouch 方法,
並在 onFling 方法判斷滑動的邏輯。
以及第23~26行的手勢和 layout 物件的連結

layout檔(fling_gesture_example_main_activity.xml)
<?xml version="1.0" encoding="utf-8"?>  
<android.support.constraint.ConstraintLayout
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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/basic_layout_activity"
tools:context=".FlingGestureExampleMainActivity">

<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>

</android.support.constraint.ConstraintLayout>

重點為 ConstraintLayout 建立 id,以便在程式碼中參考。

以上便是讓 Activity 加入滑動手勢的判斷,若是想讓該 Activity中
的 ListView 也可偵測滑動,作法相當簡單,直接讓該 ListView 呼叫 setOnTouchListener 和 setLongClickable 即可。
        mPatrolPointListView = getListView();  
mPatrolPointListViewAdapter =
new PatrolPointListViewAdapter(this, mPatrolPointListPresenter.getPatrolPointItemLayout(firstPage));
setListAdapter(mPatrolPointListViewAdapter);
...

mPatrolPointListView.setOnTouchListener(this);
mPatrolPointListView.setLongClickable(true);

 

Orignal From: 在Activity中判斷滑動手勢

android.util.Log 列印訊息內容太多無法完全顯示

使用 android.util.Log 列印訊息時,若訊息內容太多就會出現無法完全顯示訊息內容的情況。

解決的方法就是分段列印,如下
    private void logLongMessage(String TAG, String message) {  
int maxMessageSize = 2000;
for (int i = 0; i <= message.length() / maxMessageSize; i++) {
int start = i * maxMessageSize;
int end = (i + 1) * maxMessageSize;
end = end > message.length() ? message.length() : end;
Log.d(TAG, message.substring(start, end));
}
}

 

Orignal From: android.util.Log 列印訊息內容太多無法完全顯示

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews