直接上代码了同学们, webview 主要设置settings,对js的支持,长按图片可以获取下载地址,弹出menuview 下载 通知。
应用内View 点击下载,把resource 转出bitmap 保存到指定目录并加入相册,通知刷新。
Ps:
1. 保存文件路径 一定要是 外部存储( mnt/sdcard/xxx/imgs/xxx.jpeg) , 如果是内部存储 相册内会不显示 ( mnt/sdcard/android/data/xxxApp/imgs/xxx.jpeg)
2.保存的图片格式也要jpeg,否则某些手机在相册内也不显示
3.写文件的时候 请考虑实现 动态授权 EasyPermission
WebView >>>
package com.libratone.v3.activities;
import android.animation.ObjectAnimator;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.webkit.URLUtil;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.libratone.R;
import com.libratone.v3.DeviceRemovedEvent;
import com.libratone.v3.LibratoneApplication;
import com.libratone.v3.enums.DeviceTypeModel;
import com.libratone.v3.enums.MyMusicType;
import com.libratone.v3.model.AbstractSpeakerDevice;
import com.libratone.v3.model.GumLinkServiceStatus;
import com.libratone.v3.model.GumServiceAccount;
import com.libratone.v3.model.LibartoneAdManager;
import com.libratone.v3.model.ManualGuide;
import com.libratone.v3.net.AudioGumMusicRequest;
import com.libratone.v3.net.AudioGumRequest;
import com.libratone.v3.net.GumCallback;
import com.libratone.v3.net.NetworkProber;
import com.libratone.v3.util.Constants;
import com.libratone.v3.util.DeviceManager;
import com.libratone.v3.util.FavoriteChannelUtil;
import com.libratone.v3.util.GTLog;
import com.libratone.v3.util.SystemConfigManager;
import com.libratone.v3.util.ToastHelper;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.List;
import java.util.Map;
import okhttp3.ResponseBody;
import static com.libratone.v3.net.AudioGumRequest.audiogum_host;
import static com.libratone.v3.util.Constants.JAVASCRIPT;
import static com.libratone.v3.util.Constants.WEBVIEW_ACCESS_DEVICEMODE;
import static com.libratone.v3.util.Constants.WEBVIEW_ACCESS_URL;
import static com.libratone.v3.util.Constants.WEBVIEW_CLOSE_ENABLE;
import static com.libratone.v3.util.Constants.WEBVIEW_FONTMAX_ENABLE;
import static com.libratone.v3.util.Constants.WEBVIEW_RETURN_HOMEPAGE;
import static com.libratone.v3.util.Constants.WEBVIEW_TITLE;
import static com.libratone.v3.util.ParseCONST.getCurrentLanuageForNetAccess;
public class WebPageDisplayActivity extends BaseActivity {
protected static final String TAG = WebPageDisplayActivity.class.getSimpleName();
protected String mSourceUrl;
private boolean isReturnHomePage;
private boolean isEnableCloseButton;
private boolean isEnableFondMax;
protected boolean isLogin = false;
private ImageView mCloseButton;
private ImageView mBackButton;
private TextView pagetitle;
private WebView mWebview;
private ObjectAnimator progressAnim = null;
private ObjectAnimator alphaAnim = null;
private List<ManualGuide> mGuideUrlList = null;
private String javaScript;
private Handler delayHandler = new Handler();
private Runnable delayRunnable = new Runnable() {
@Override
public void run() {
mWebview.setVisibility(View.VISIBLE);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview);
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
if (getIntent() == null) {
finish();
}
if (NetworkProber.isNetworkAvailable(LibratoneApplication.getContext())) {
initView();
} else {
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
handlerBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mWebview != null) {
mWebview.destroy();
}
if (broadcastReceiver != null) {
unregisterReceiver(broadcastReceiver);
}
}
@Override
protected void handleFailData(String reason, boolean finishPage) {
super.handleFailData(reason, finishPage);
}
private void handlerBack() {
if (mWebview != null && mWebview.canGoBack()) {
if (!TextUtils.isEmpty(javaScript)) {
mWebview.setVisibility(View.INVISIBLE);
}
mWebview.goBack();
} else {
if (isReturnHomePage) {
ToolBarActivity.goHome(this);
} else {
finish();
}
}
}
protected void initView() {
Intent initIntent = getIntent();
isEnableCloseButton = initIntent.getBooleanExtra(WEBVIEW_CLOSE_ENABLE, false);
isEnableFondMax = initIntent.getBooleanExtra(WEBVIEW_FONTMAX_ENABLE, false);
javaScript = initIntent.getStringExtra(JAVASCRIPT);
pagetitle = findViewById(R.id.Webview_title);
mCloseButton = findViewById(R.id.webview_close);
if (isEnableCloseButton) {
mCloseButton.setVisibility(View.VISIBLE);
mCloseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
} else {
mCloseButton.setVisibility(View.GONE);
}
mBackButton = findViewById(R.id.webview_back);
mBackButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handlerBack();
}
});
mWebview = findViewById(R.id.webview_policy);
final ProgressBar progressbar = findViewById(R.id.progressbar);
mWebview.setWebChromeClient(new WebChromeClient() {
private boolean loading = false;
@Override
public void onProgressChanged(WebView view, int newProgress) {
GTLog.w(TAG, "onProgressChanged:" + newProgress);
if (newProgress == 100) {
if (progressAnim != null) {
progressAnim.cancel();
}
if (alphaAnim != null) {
alphaAnim.cancel();
}
loading = false;
progressAnim = ObjectAnimator.ofInt(progressbar, "progress", 100).setDuration(200);
alphaAnim = ObjectAnimator.ofFloat(progressbar, "alpha", 0).setDuration(400);
progressAnim.start();
alphaAnim.start();
} else if (newProgress <= 20 && !loading) {
if (progressAnim != null) {
progressAnim.cancel();
}
if (alphaAnim != null) {
alphaAnim.cancel();
}
loading = true;
progressbar.setProgress(0);
progressbar.setAlpha(1.0f);
progressAnim = ObjectAnimator.ofInt(progressbar, "progress", 95);
progressAnim.setInterpolator(new DecelerateInterpolator(3));
progressAnim.setDuration(20_000).start();
}
}
});
//add some setting for webview
final WebSettings settings = mWebview.getSettings();
//for screen adaptive
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
//zoom support
settings.setSupportZoom(true);
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setSavePassword(false);
mWebview.clearCache(true); // 打开时清除cache,保证语言切换时能刷到正确的页面。
if (isEnableFondMax) {
//200 mean 200%
settings.setTextZoom(200);
} else {
// 100 man 100%
//The default is 100
settings.setTextZoom(100);
}
//support js
settings.setJavaScriptEnabled(true);
settings.setJavaScriptCanOpenWindowsAutomatically(true);
settings.setDomStorageEnabled(false);
settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
registerForContextMenu(mWebview);
//cache setting
// settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
// settings.setDomStorageEnabled(true);
// settings.setDatabaseEnabled(true);
// settings.setAppCacheEnabled(true);
mWebview.setWebViewClient(new WebViewClient() {
private boolean isLoading = false;
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
GTLog.v(TAG, "onPageFinished" + url);
injectJs(view, url, false);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
GTLog.v(TAG, "onPageStarted" + url);
injectJs(view, url, true);
}
@Override
public void onPageCommitVisible(WebView view, String url) {
GTLog.v(TAG, "onPageCommitVisible" + url);
injectJs(view, url, false);
}
@Override
public void onLoadResource(WebView view, String url) {
GTLog.v(TAG, "onLoadResource" + url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//load page in this webview.
GTLog.v(TAG, "shouldOverrideUrlLoading: " + url);
handleUrlLoading(view, url);
return true;
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {//-2,net::ERR_NAME_NOT_RESOLVED
super.onReceivedError(view, errorCode, description, failingUrl);
if (errorCode == WebViewClient.ERROR_HOST_LOOKUP
|| errorCode == WebViewClient.ERROR_CONNECT
|| errorCode == WebViewClient.ERROR_TIMEOUT) {
if (description != null) {
GTLog.e(TAG, "onReceivedError error: " + description);
}
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
}
/**
* only show/hide when there is inject js to hide dom changing.
* since some phones call onPageFinished, some phones call onPageCommitVisible.
* have to run delayRunnable in both function
* @param prepare: true is prepare to inject, false is real inject.
*/
private void injectJs(WebView view, String url, boolean prepare) {
if (TextUtils.isEmpty(javaScript)) {
return;
}
if (prepare) {
isLoading = true;
delayHandler.removeCallbacks(delayRunnable);
mWebview.setVisibility(View.INVISIBLE);
} else {
if (isLoading) {
isLoading = false;
if (url.startsWith("https://")) {
String[] jsCodes = javaScript.split(";");
for (String jsCode : jsCodes) {
view.evaluateJavascript("javascript:" + jsCode, null);
}
}
delayHandler.removeCallbacks(delayRunnable);
delayHandler.postDelayed(delayRunnable, 200);
}
}
}
});
Bundle retBundle = initIntent.getExtras();
if (retBundle != null) {
if (retBundle.getSerializable(WEBVIEW_ACCESS_DEVICEMODE) != null) {
//for get link from aum case
DeviceTypeModel retDeviceTypeModel = (DeviceTypeModel) retBundle.getSerializable(WEBVIEW_ACCESS_DEVICEMODE);
String reStr = getResources().getString(retDeviceTypeModel.getName());
setTitle(reStr);
String initParam = retDeviceTypeModel.getOtaName();
if (!TextUtils.isEmpty(initParam)) {
GTLog.d(TAG, "initView para: " + initParam);
//access augiogum,
//for manual, "_user_guide" must added at the end of devicename
getDeviceManual(initParam + "_user_guide");
}
} else {
//for have link case
mSourceUrl = initIntent.getStringExtra(WEBVIEW_ACCESS_URL);
isReturnHomePage = initIntent.getBooleanExtra(WEBVIEW_RETURN_HOMEPAGE, false);
String title = initIntent.getStringExtra(WEBVIEW_TITLE);
setTitle(title);
}
loadPage();
}
}
private void setTitle(String title) {
if (TextUtils.isEmpty(title)) {
return;
}
title = title.replaceAll("\\n", " ");
if (title.startsWith("TRACK Air")) { // 对air和air+做特殊处理
pagetitle.setText(title);
} else {
pagetitle.setText(title.toUpperCase());
}
}
protected void handleBindResult() {
//success login napster by audiogum
Intent intent = getIntent();
if (intent.getBooleanExtra("fromSS", false)) {
MyMusicType channelType = (MyMusicType) intent.getSerializableExtra("service");
GumChannelBrowseActivity.goToChannelBrowse(instance, channelType);
}
finish();
}
protected void handleUrlLoading(WebView view, String url) {
GTLog.d(TAG, "shouldOverrideUrlLoading: " + url);
//https://api.audiogumlabs.com/v1/authorize/tidal/complete?code=
//https://api.audiogum.com/v1/authorize/napster/complete?code=ZjA4MGFjMzMtM2Y5OS00MWZhLWEwZWYtMmVmZGM2YmM3ZDU2
String accessToken = null;
String serviceName = null;
if (WebPageDisplayActivity.this instanceof ChannelLoginActivity) {
MyMusicType channelType = (MyMusicType) getIntent().getSerializableExtra("service");
serviceName = channelType.getId().toLowerCase();
String authorizeUrl = "/v1/authorize/" + serviceName + "/complete?code=";
if ((!TextUtils.isEmpty(url)) && url.contains(authorizeUrl)) {
accessToken = url.substring(url.indexOf("code=") + 5);
}
}
if ((!TextUtils.isEmpty(accessToken))) {
GTLog.d(TAG, "accessToken: " + accessToken);
//send access token to audiogum
AudioGumMusicRequest.putServiceToken(serviceName, accessToken, new GumCallback<GumServiceAccount>() {
@Override
public void onSuccess(GumServiceAccount responseObj) {
//update user data
AudioGumRequest.getUser(null);
//add this to get linked service.
getLinkedMusicServiceListAndFreshDeviceChannel();
handleBindResult();
}
@Override
public void onFailure(int code, ResponseBody body) {
}
@Override
public void onTimeout(String message) {
}
});
} else if ((!TextUtils.isEmpty(url))
&& (url.contains("libratone.com")
|| url.contains(audiogum_host))
&& !url.contains("mailto:")) {
//webview cannot handler mailto case
view.loadUrl(url);
} else if ((!TextUtils.isEmpty(url)) && (url.contains("spotify"))) {
view.loadUrl(url);
} else if (isLogin) {
view.loadUrl(url);
} else {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(url));
LibratoneApplication.getContext().startActivity(intent);
} catch (Exception e) {
// not openable url, just do nothing
e.printStackTrace();
}
}
}
protected void loadUrl(WebView view, String url) {
view.loadUrl(url);
}
private void getDeviceManual(final String srcParam) {
AudioGumRequest.getDeviceManualConfig(srcParam, new GumCallback<JsonObject>() {
@Override
public void onSuccess(JsonObject responseObj) {
if (responseObj != null) {
try {
Gson gson = new Gson();
if (responseObj.has(srcParam)) {
JsonElement member = responseObj.get(srcParam);
if (!member.isJsonNull()) {
mGuideUrlList = gson.fromJson(member.getAsJsonArray(), new
TypeToken<List<ManualGuide>>() {
}.getType());
}
findAndTriggerManual();
} else {
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
} catch (JsonSyntaxException e) {
GTLog.e(TAG, "getDeviceManual-> exception: " + e.getMessage());
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
} else {
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
}
@Override
public void onFailure(int code, ResponseBody body) {
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
@Override
public void onTimeout(String message) {
handleFailData(Constants.ERROR_CONNACT_FAILED, true);
}
});
}
private void findAndTriggerManual() {
if (mGuideUrlList != null && mGuideUrlList.size() > 0) {
boolean bFound = false;
String currLang = getCurrentLanuageForNetAccess();
//make sure mGuideUrlList have node.
for (ManualGuide item : mGuideUrlList) {
if (item.getUrl() != null
&& (item.getLang() != null
&& currLang.equalsIgnoreCase(item.getLang())
|| (item.getLanguage() != null
&& currLang.equalsIgnoreCase(item.getLanguage())))) {
mSourceUrl = item.getUrl();
bFound = true;
break;
}
}
if (bFound) {
//found, load it.
loadPage();
} else {
//find default en case
for (ManualGuide item : mGuideUrlList) {
if (item.getUrl() != null
&& (item.getLang() != null
&& "en".equalsIgnoreCase(item.getLang())
|| (item.getLanguage() != null
&& "en".equalsIgnoreCase(item.getLanguage())))) {
mSourceUrl = item.getUrl();
break;
}
}
if (!TextUtils.isEmpty(mSourceUrl)) {
loadPage();
} else {
ToastHelper.showToast(instance, LibratoneApplication.getContext().getResources().getString
(R.string.bt_tws_search_fail_title), null);
finish();
}
}
} else {
ToastHelper.showToast(instance, LibratoneApplication.getContext().getResources().getString
(R.string.bt_tws_search_fail_title), null);
finish();
}
}
protected void loadPage() {
if (NetworkProber.isNetworkAvailable(LibratoneApplication.getContext())
&& !TextUtils.isEmpty(mSourceUrl)
&& mWebview != null) {
mWebview.loadUrl(mSourceUrl);
}
}
private static void getLinkedMusicServiceListAndFreshDeviceChannel() {
AudioGumMusicRequest.getLinkedServiceStatus(new GumCallback<Map<String, GumLinkServiceStatus>>() {
@Override
public void onSuccess(Map<String, GumLinkServiceStatus> responseObj) {
SystemConfigManager.getInstance().setGumLinkedServicesStatus(responseObj);
//refresh channel
FavoriteChannelUtil.refreshChannel();
}
@Override
public void onFailure(int code, ResponseBody body) {
}
@Override
public void onTimeout(String message) {
}
});
}
@Override
public void onCreateContextMenu(ContextMenu contextMenu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) {
super.onCreateContextMenu(contextMenu, view, contextMenuInfo);
final WebView.HitTestResult webViewHitTestResult = mWebview.getHitTestResult();
if (webViewHitTestResult.getType() == WebView.HitTestResult.IMAGE_TYPE ||
webViewHitTestResult.getType() == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE) {
//contextMenu.setHeaderTitle("网页中下载图片");
contextMenu.add(0, 1, 0, "保存图片")
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem menuItem) {
String DownloadImageURL = webViewHitTestResult.getExtra();
if (URLUtil.isValidUrl(DownloadImageURL)) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(DownloadImageURL));
request.allowScanningByMediaScanner();
// 下载过程和下载完成后通知栏有通知消息。
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE | DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
fileName = System.currentTimeMillis() + ".jpeg";
//filePath = getExternalFilesDir("/imgs").getAbsolutePath();
//设置图片的保存路径
//request.setDestinationInExternalFilesDir(WebPageDisplayActivity.this, "/imgs", "/" + fileName);
filePath = Environment.getExternalStoragePublicDirectory("/Libratone/imgs").getAbsolutePath();
request.setDestinationInExternalPublicDir("/Libratone/imgs", "/" + fileName);
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
long Id = downloadManager.enqueue(request);
listener(Id);
} else {
ToastHelper.showToast(WebPageDisplayActivity.this, "保存失败");
}
return false;
}
});
}
}
private String fileName;
private String filePath;
private BroadcastReceiver broadcastReceiver;
private void listener(final long Id) {
// 注册广播监听系统的下载完成事件。
IntentFilter intentFilter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long ID = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (ID == Id) {
// 其次把文件插入到系统图库
try {
MediaStore.Images.Media.insertImage(getContentResolver(),
filePath, fileName, null);
} catch (FileNotFoundException e) {
e.printStackTrace();
ToastHelper.showToast(WebPageDisplayActivity.this, "保存失败");
}
// 最后通知图库更新
File file = new File(filePath, fileName);
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.getAbsolutePath())));
MediaScannerConnection.scanFile(LibratoneApplication.getContext(), new String[]{file.getAbsolutePath()}, new String[]{"image/jpeg"}, null);
ToastHelper.showToast(WebPageDisplayActivity.this, "保存成功");
}
}
};
registerReceiver(broadcastReceiver, intentFilter);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onEventMainThread(DeviceRemovedEvent event) {
AbstractSpeakerDevice device = DeviceManager.getInstance().getDevice(event.getKey());
if (LibartoneAdManager.getInstance().speakerContainAd(device.getSerialNum())) {
askAndQuitActivity(R.string.close_device);
}
}
}
ImageView >>>
package com.libratone.v3.activities
import android.Manifest
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.Message
import android.provider.MediaStore
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.*
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import com.libratone.R
import com.libratone.v3.DeviceRemovedEvent
import com.libratone.v3.LibratoneApplication
import com.libratone.v3.activities.MyProfileActivity.RC_CHANGE_STORAGE_STATE_PERM
import com.libratone.v3.model.AbstractSpeakerDevice
import com.libratone.v3.model.LSSDPAd
import com.libratone.v3.model.LibartoneAdManager
import com.libratone.v3.util.Constants
import com.libratone.v3.util.DeviceManager
import com.libratone.v3.util.ToastHelper
import com.libratone.v3.widget.RecyclerViewSpacesItemDecoration
import com.libratone.wxapi.TencentAuthorizeDataReq
import kotlinx.android.synthetic.main.activity_gift.*
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.io.FileOutputStream
import java.lang.ref.WeakReference
class GiftActivity : BaseActivity() {
var showTips: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_gift)
setTitle(R.string.ad_huodong)
showTips = intent.getBooleanExtra("SHOW_TIPS", false)
if (LibartoneAdManager.getInstance().adList.isEmpty()) {
handler = MyHandler(this)
ad_empty_rl.visibility = View.VISIBLE
ad_sv.visibility = View.GONE
registerForContextMenu(ad_empty_iv)
} else {
initView()
}
}
fun initView() {
ad_empty_rl.visibility = View.GONE
ad_sv.visibility = View.VISIBLE
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.addItemDecoration(RecyclerViewSpacesItemDecoration(10, 0, 20, 20))
recyclerView.adapter = AdAdapter(this)
if (showTips) {
bottom_tips.visibility = View.GONE
} else {
bottom_tips.visibility = View.VISIBLE
}
}
inner class AdAdapter(context: Context?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val mContext = context
private val mLayoutInflater: LayoutInflater = LayoutInflater.from(mContext)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = mLayoutInflater.inflate(R.layout.listview_ad_item, parent, false)
val holder = ItemHolder(view)
holder.ivIcon = view.findViewById(R.id.ivIcon)
holder.tvName = view.findViewById(R.id.tvName)
holder.recyclerView = view.findViewById(R.id.recyclerView)
return holder
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = LibartoneAdManager.getInstance().adList[position]
val itemHolder = holder as ItemHolder
var speaker: AbstractSpeakerDevice = DeviceManager.getInstance().getDeviceBySN(item.serialNum)
itemHolder.ivIcon?.setImageResource(AbstractSpeakerDevice.getIconId(speaker.model, speaker.deviceColor))
itemHolder.tvName?.text = speaker.name
itemHolder.recyclerView!!.layoutManager = LinearLayoutManager(mContext)
itemHolder.recyclerView!!.adapter = AdItemAdapter(item, mContext, item.activityList)
}
override fun getItemCount(): Int {
return LibartoneAdManager.getInstance().adList.size
}
}
private class ItemHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
var ivIcon: ImageView? = null
var tvName: TextView? = null
var recyclerView: RecyclerView? = null
}
inner class AdItemAdapter(node: LSSDPAd, context: Context?, list: List<LSSDPAd.MemberActivity>?) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val parent = node
private val mList = list
private val mLayoutInflater: LayoutInflater = LayoutInflater.from(context)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view = mLayoutInflater.inflate(R.layout.listview_ad_item_item, parent, false)
val holder = ItemRecyclerHolder(view)
holder.item_ll = view.findViewById(R.id.item_ll)
holder.title = view.findViewById(R.id.title)
holder.line = view.findViewById(R.id.line)
return holder
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val itemHolder = holder as ItemRecyclerHolder
var activity: LSSDPAd.MemberActivity = mList!!.get(position)
itemHolder.title?.text = activity.name
if (position == mList.size - 1) {
itemHolder.line?.visibility = View.GONE
} else {
itemHolder.line?.visibility = View.VISIBLE
}
itemHolder.item_ll?.setOnClickListener {
goToActivity(parent.serialNum, activity)
}
}
override fun getItemCount(): Int {
return mList!!.size
}
}
private class ItemRecyclerHolder internal constructor(view: View) : RecyclerView.ViewHolder(view) {
var title: TextView? = null
var line: View? = null
var item_ll: LinearLayout? = null
}
fun goToActivity(serialNum: String, activity: LSSDPAd.MemberActivity?) {
if (activity!!.type.equals("web")) {
val intent = Intent(this, WebPageDisplayActivity::class.java)
intent.putExtra(Constants.WEBVIEW_ACCESS_URL, activity!!.url + serialNum)
intent.putExtra(Constants.WEBVIEW_RETURN_HOMEPAGE, true)
intent.putExtra(Constants.WEBVIEW_TITLE, activity!!.name)
intent.putExtra(Constants.WEBVIEW_CLOSE_ENABLE, true)
startActivity(intent)
} else if (activity.type.equals("weapp")) {
if (TencentAuthorizeDataReq.isWechatInstalled() && TencentAuthorizeDataReq.isSupportedMiniProgram()) {
TencentAuthorizeDataReq.triggerWexinMiniProgram(LibratoneApplication.getContext(), activity!!.url)
} else {
ToastHelper.showToast(this, "请安装微信")
}
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(event: DeviceRemovedEvent) {
recyclerView?.adapter?.notifyDataSetChanged()
if (LibartoneAdManager.getInstance().adList.isEmpty()) {
gotoSoundspace()
}
}
private class MyHandler(activity: GiftActivity) : Handler() {
private val mActivity: WeakReference<GiftActivity>
init {
mActivity = WeakReference(activity)
}
override fun handleMessage(msg: Message) {
val activity = mActivity.get() ?: return
when (msg.what) {
0 -> ToastHelper.showToast(activity, "保存失败")
1 -> ToastHelper.showToast(activity, "保存成功")
2 -> ToastHelper.showToast(activity, "图片已保存")
}
}
}
private var handler: MyHandler? = null
override fun onCreateContextMenu(menu: ContextMenu?, v: View?, menuInfo: ContextMenu.ContextMenuInfo?) {
super.onCreateContextMenu(menu, v, menuInfo)
menu?.add(0, 1, 0, "保存图片")?.setOnMenuItemClickListener(MenuItem.OnMenuItemClickListener {
var permissions = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
checkPermission(permissions, RC_CHANGE_STORAGE_STATE_PERM, "")
false
})
}
override fun getWriteExternalPermission(flag: Boolean) {
super.getWriteExternalPermission(flag)
if (flag) {
val filePath = Environment.getExternalStorageDirectory().absolutePath + "/Libratone/imgs"
val fileDir = File(filePath)
if (fileDir.exists()) {
handler?.sendEmptyMessage(2)
} else {
fileDir.mkdirs()
val fileName = "qrcode.jpeg"
val file = File(filePath, fileName)
try {
val fos = FileOutputStream(file)
val bmp = BitmapFactory.decodeResource(resources, R.drawable.qrcode)
bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos)
fos.flush()
fos.close()
MediaStore.Images.Media.insertImage(LibratoneApplication.getContext().contentResolver,
filePath, fileName, null)
LibratoneApplication.getContext().sendBroadcast(Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse(file.absolutePath)))
MediaScannerConnection.scanFile(LibratoneApplication.getContext(), arrayOf(file.absolutePath), arrayOf("image/jpeg"), null)
handler?.sendEmptyMessage(1)
} catch (e: Exception) {
e.printStackTrace()
handler?.sendEmptyMessage(0)
}
}
}
}
}