오늘은 내 앱의 화면에 올라온 내용중에 webView 에 들어 있는 것을 이미지 파일로 만들고 pdf 파일에 담아서 공유하는 기능을 구현해 보고자 한다.
먼저할 것은 인터넷 접속을 위한 권한 부여
<uses-permission android:name="android.permission.INTERNET"/>
굳이 사용자에게 허가를 받지 않아도 된다. 그 다음에 layout 을 구성해 보았다.
보는 것 처럼 화면에는 버튼 한개와 webView 만 한개 만들어 두었다.
layout의 코드는 다음과 같이.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<Button
android:id="@+id/pdfShare"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:layout_marginTop="16dp"
android:text="Button"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<WebView
android:id="@+id/webView"
android:layout_width="0dp"
android:layout_height="645dp"
android:layout_marginTop="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/pdfShare" />
</androidx.constraintlayout.widget.ConstraintLayout>
그 다음은 이미지를 임시로 저장하고 그걸 pdf 로 전환하는 방법을 구현할 예정이기 때문에 임시저장소를 선택할 수 있도록 file_provider 의 값을 등록해 준다. res/xml 폴더에 file_provider.xml 로 아래 내용을 저장해 주었다.
cache 을 사용하는 것은 파일 저장을 하기 위해서 사용자에게 권한을 허가 받지 않아도 되기 떄문이다.
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path name="cache" path="."/>
</paths>
다음은 activity을 구현해 보아야겠다.
먼저 webView 에 나의 블로그를 load할 수 있도록 하고, load가 다 되었다면 그 때 이미지 파일에 임시 저장을 한 다음,
버튼을 클릭하면 그 이미지 파일을 열어서 공유하는 intent 을 호출 하도록 구현할 예정이다.
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.app.ActivityCompat;
import androidx.core.app.ShareCompat;
import androidx.core.content.FileProvider;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Toast;
import com.billcoreatech.pdftest.databinding.ActivityMainBinding;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
Bitmap bitmap, scalebmp ;
int pageWidth = 1200 ;
ActivityMainBinding bind ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bind = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(bind.getRoot());
bind.webView.loadUrl("https://billcorea.tistory.com");
bind.webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
new Background().execute();
}
});
bind.pdfShare.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (createPDF ()) {
File pdfFile = new File(getCacheDir(), "/pizza.pdf");
Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), getApplicationContext().getPackageName()+".fileProvider", pdfFile);
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(shareIntent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, contentUri,
Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
startActivity(Intent.createChooser(shareIntent, "PDF 공유"));
};
}
});
}
private boolean createPDF() {
File file = new File(getCacheDir(), "/aaaa.png");
if (!file.isFile()) {
Toast.makeText(getApplicationContext(), "파일 생성이 되지 않았습니다.", Toast.LENGTH_SHORT).show();
return false ;
}
bitmap = BitmapFactory.decodeFile(getCacheDir().toString() + "/aaaa.png");
PdfDocument pdfDocument = new PdfDocument();
Paint paint = new Paint();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), bitmap.getHeight(), 1).create();
PdfDocument.Page page = pdfDocument.startPage(pageInfo);
Canvas canvas = page.getCanvas();
canvas.drawBitmap(bitmap, 0, 0, paint);
pdfDocument.finishPage(page);
File file1 = new File(getCacheDir(), "/pizza.pdf");
try {
pdfDocument.writeTo(new FileOutputStream(file1));
} catch (IOException e) {
return false ;
}
pdfDocument.close();
return true ;
}
class Background extends AsyncTask<Void, Void, Bitmap>
{
@Override
protected Bitmap doInBackground(Void... params)
{
try
{
Thread.sleep(2000);
Bitmap bitmap = Bitmap.createBitmap(bind.webView.getWidth(), bind.webView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
bind.webView.draw(canvas);
return bitmap;
}
catch (InterruptedException e){}
catch (Exception e){}
return null;
}
@SuppressLint("WrongThread")
@Override
protected void onPostExecute(Bitmap bm)
{
try {
OutputStream fOut = null;
File file = new File(getCacheDir(), "/aaaa.png");
fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 50, fOut);
fOut.flush();
fOut.close();
bm.recycle();
Log.e(TAG, "fileName=" + getCacheDir() + "/aaaa.png");
Toast.makeText(getApplicationContext(), "공유할 파일이 생성되었습니다.", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "" + e.toString());
}
}
}
}
webView 에 load는 시간이 소요 되기 떄문에 Background 로 load 된 이미지를 png 로 변환하도록 구현이 되었고,
버튼을 클릭하면 그 때 png 파일이 있는 지 체크 해서 없으면 알림을 보여주고, 있으면 해당 이미지 파일을 pdf 로 전환해서 하고, pdf 가 생성되었다면, intent 을 호출해서 공유하도록 구현하는 방식이다.
다만, API 32 기준으로 AVD에서 테스트를 해 보면서 오류 로그가 보이기는 했으나, 실행은 되었다. provider 에게 uri read 권한을 주어야 할 것 같은데, 아직 구글링을 했을 때 정확한 해소 방안은 찾을 수 없었다.
어떻게 하지 ?
알게될 날이 올까 ?
오류 해소를 위해서 다음 링크 까지는 해 보았으나... 아직 ... ㅠㅠ;;
'모바일 앱(안드로이드)' 카테고리의 다른 글
안드로이드 앱 만들기 사전 출시 보고서 접근성에 대해서 (2) | 2022.03.08 |
---|---|
안드로이드 앱 만들기 sendBroadcast 암시적 ? 명시적 (3) | 2022.03.06 |
안드로이드 앱 만들기 : google map(구글맵) platform 사용자에게 보낸 메일 (2) | 2022.02.21 |
안드로이드 앱 만들기 studio Chipmunk 다람쥐 에서 Dolphin 돌고래 버전으로 (3) | 2022.02.19 |
안드로이드 앱 만들기 splash screen 만들기 (2) (2) | 2022.02.18 |