Электронная библиотека » Тимур Машнин » » онлайн чтение - страница 11


  • Текст добавлен: 16 октября 2020, 07:59


Автор книги: Тимур Машнин


Жанр: Компьютеры: прочее, Компьютеры


Возрастные ограничения: +12

сообщить о неприемлемом содержимом

Текущая страница: 11 (всего у книги 20 страниц)

Шрифт:
- 100% +

Activity + Service + AIDL

AIDL интерфейс используется, если взаимодействие с сервисом производится из разных приложений и ваш сервис должен обеспечивать многопоточность.

Для создания AIDL интерфейса в Android Studio нажмем правой кнопкой мышеи на модуле и выберем New | AIDL | AIDL File.

В результате, в каталоге src/main модуля будет создана папка aidl с файлом интерфейса, на основе которого при сборке модуля в каталоге build/generated будет сгенерирована Java-реализация AIDL интерфейса.

Сгенерированная Java-реализация AIDL интерфейса представляет собой класс-заглушку, который расширяет класс Binder и поэтому может быть возвращен методом onBind Bound-сервиса.

Возвращенный в активность экземпляр AIDL-класса может содержать методы, вызываемые активностью.

Код AIDL-интерфейса:

package com. application;

interface IAidlInterface {

String getResult (String url);

}

Код Bound-сервиса:

package com. application;


import android.app.Service;

import android.content.Context;

import android.content.Intent;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android. os. IBinder;;

import android.os.RemoteException;

import org. json. JSONObject;

import java.io.BufferedReader;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net. URL;

import java.text.SimpleDateFormat;

import java.util.Calendar;

import java.util.concurrent.Callable;

import java.util.concurrent. FutureTask;

import java.util.concurrent.RunnableFuture;


public class WebBoundService extends Service {


public WebBoundService () {

}


@Override

public IBinder onBind (Intent intent) {

return new IAidlInterface.Stub () {

public String getResult (String url) throws RemoteException {


final String urlString=url;

String resp=«»;


RunnableFuture f = new FutureTask (new Callable <String> () {

@Override

public String call () throws Exception {

String data=«»;

ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

NetworkInfo networkInfo = connMgr.getActiveNetworkInfo ();

if (networkInfo!= null && networkInfo.isConnected () && networkInfo.isAvailable ()) {

InputStream is = null;

URL url = null;

url = new URL (urlString);

HttpURLConnection conn = (HttpURLConnection) url. openConnection ();

conn.setReadTimeout (10000 /* milliseconds */);

conn.setConnectTimeout (15000 /* milliseconds */);

conn.setRequestMethod («GET»);

conn.setDoInput (true);

conn.connect ();

is = conn.getInputStream ();

// Convert the InputStream into a string

BufferedReader br = null;

StringBuilder sb = new StringBuilder ();

String line;

br = new BufferedReader (new InputStreamReader (is));

while ((line = br.readLine ())!= null) {

sb. append (line);

}

String contentAsString = sb.toString ();

is.close ();

conn. disconnect ();

JSONObject reader = new JSONObject (contentAsString);

JSONObject main = reader.getJSONObject («main»);

String temp = main.getString («temp»);

Calendar c = Calendar.getInstance ();

SimpleDateFormat df = new SimpleDateFormat («yyyy-MM-dd HH: mm: ss»);

String formattedDate = df.format(c.getTime ());

data = formattedDate + " temp: " + temp;

return data;

} else {

return data;

}

}

});

new Thread(f).start ();

try {

resp= (String) f.get ();

} catch (Exception e) {

e.printStackTrace ();

}

return resp;

}

};

}

}

Здесь в реализации метода AIDL-интерфейса данные получаются из Интернета в отдельном потоке.

Для возврата данных из отдельного потока используется класс FutureTask.

Код активности:

package com. application;


import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.content.SharedPreferences;

import android.net.ConnectivityManager;

import android.net.NetworkInfo;

import android. os. Bundle;

import android. os. IBinder;

import android.os.RemoteException;

import android.support. v7.app. AppCompatActivity;

import android. util. Log;

import android.view.Menu;

import android.view.MenuItem;

import android. widget. TextView;


public class MainActivity extends AppCompatActivity {


private final Context context=this;

private ServiceConnection sConn;

private boolean bound = false;

private IAidlInterface service;


@Override

protected void onCreate (Bundle savedInstanceState) {

super. onCreate (savedInstanceState);

setContentView(R.layout.activity_main);

sConn = new ServiceConnection () {

public void onServiceConnected (ComponentName name, IBinder binder) {

service = IAidlInterface.Stub.asInterface ((IBinder) binder);

String data=«»;


try {

data = http://api.openweathermap.org/data/2.5/weather?q=London,uk");tResult (»service.ge

} catch (RemoteException e) {

e.printStackTrace ();

}


if (!data. equals (»»)) {

SharedPreferences sharedPref = context.getSharedPreferences("com.application.PREFERENCE_FILE_KEY», Context.MODE_PRIVATE);

SharedPreferences. Editor editor = sharedPref. edit ();

editor. putString («data», data);

editor.commit ();

TextView textView = (TextView) findViewById(R.id.textView);

textView.setText (data);

} else {

SharedPreferences sharedPref = context.getSharedPreferences("com.application.PREFERENCE_FILE_KEY», Context.MODE_PRIVATE);

String savedData = sharedPref.getString («data», «unknown data»);

TextView textView = (TextView) findViewById(R.id.textView);

textView.setText (savedData);

}

bound = true;

}


public void onServiceDisconnected (ComponentName name) {

service = null;

bound = false;

}

};

Intent intent = new Intent(MainActivity.this, WebBoundService.class);

bindService(intent,sConn,this.BIND_AUTO_CREATE);

}


@Override

protected void onDestroy () {

super. onDestroy ();

if (bound) {

unbindService (sConn);

bound = false;

}

}


@Override

public boolean onCreateOptionsMenu (Menu menu) {

getMenuInflater().inflate(R.menu.menu_main, menu);

return true;

}


@Override

public boolean onOptionsItemSelected (MenuItem item) {


int id = item.getItemId ();

if (id == R.id.action_settings) {

return true;

}

return super. onOptionsItemSelected (item);

}

}

Здесь в методе onServiceConnected при соединении с Bound-сервисом получается экземпляр AIDL-класса, после этого вызывается его метод.

Отображение Toast сообщения из сервиса или потока

Handler handler = new Handler(Looper.getMainLooper ());

handler.post (new Runnable () {


@Override

public void run () {

Toast.makeText(context.getApplicationContext (),«No internet connection",Toast.LENGTH_SHORT).show ();

}

});

Изменение цвета шрифта для всей активности

В файл styles. xml в тэг <style> включим элемент:

<item name=«android: textColor»> @color/colorPrimary </item>

Получить выбранный RadioButton из RadioGroup

RadioGroup radioButtonGroup = (RadioGroup) view.findViewById(R.id.radiogroup);

int radioButtonID = radioButtonGroup.getCheckedRadioButtonId ();

RadioButton radioButton = (RadioButton) radioButtonGroup.findViewById (radioButtonID);

String str = radioButton.getText().toString ();

Сборка APK файла с большим количеством методов в коде

В Gradle файл добавить:

defaultConfig {


multiDexEnabled true

}

dependencies {


compile 'com.android.support: multidex:1.0.0»

}

android {


dexOptions {

incremental true

javaMaxHeapSize «4g»

}

}

В файл манифеста:

<application


android:name="android.support.multidex.MultiDexApplication»>

Получение Google аккаунта пользователя

Intent intent = AccountPicker.newChooseAccountIntent (null, null, new String [] {«com. google»},

true, null, null, null, null);

startActivityForResult (intent, REQUEST_CODE_ACCOUNT);


protected void onActivityResult (final int requestCode, final int resultCode, final Intent data) {

if (requestCode == REQUEST_CODE_ACCOUNT && resultCode == RESULT_OK)

{

String accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);

SharedPreferences. Editor editor = mSettings. edit ();

editor. putString («APP_PREFERENCES_ACCOUNT», accountName);

editor.commit ();

}

}

Присоединение слушателя к Button

Button button = (Button) findViewById(R.id.button_id);

button.setOnClickListener (new View. OnClickListener () {

public void onClick (View v) {

// Perform action on click

}

});

Передача изображения в Google App Engine Java Blobstore используя Google Cloud Endpoints

Выбор изображения в галереи:

Button imageButton=(Button)view.findViewById(R.id.change_profile_photo);

imageButton.setOnClickListener (new View. OnClickListener () {

public void onClick (View v) {

Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);

photoPickerIntent.setType («image/*»);

getActivity().startActivityForResult (photoPickerIntent, REQUEST_CODE_PHOTO);

}

});

protected void onActivityResult (final int requestCode, final int resultCode, final Intent data) {

if (requestCode == REQUEST_CODE_PHOTO && resultCode == RESULT_OK) {

Uri selectedImage = data.getData ();

SharedPreferences. Editor editor = mSettings. edit ();

editor. putString («APP_PREFERENCES_PHOTO», selectedImage.toString ());

editor.commit ();

}

}

Кодирование изображения в Base64-строку:

Uri imageUri = Uri.parse(mSettings.getString («APP_PREFERENCES_PHOTO»,»»));

InputStream imageStream = null;

try {

imageStream = getContext().getContentResolver ().openInputStream (imageUri);

} catch (FileNotFoundException e) {

e.printStackTrace ();

}

Bitmap bitmap = BitmapFactory.decodeStream (imageStream);

ByteArrayOutputStream outputStream = new ByteArrayOutputStream ();

bitmap.compress(Bitmap.CompressFormat.JPEG, 10, outputStream);

bitmap.recycle ();

bitmap = null;

byte [] bitmapByte = outputStream.toByteArray ();

outputStream=null;

String stringEncodedImage = Base64.encodeToString (bitmapByte, Base64.DEFAULT);

bitmapByte=null;

Отправка изображения:

private static MyApi myApiService = null;

private MyBean profile=new MyBean ();


profile.setMImage (stringEncodedImage);

ProfileDialogAsyncTask task=new ProfileDialogAsyncTask ();

task. execute (profile);

private static class ProfileDialogAsyncTask extends AsyncTask <MyBean, Integer, MyBean> {

private MyApi myApiService = null;

private ProgressBar pb;


@Override

protected void onPreExecute () {

super. onPreExecute ();

pb = (ProgressBar)context.findViewById(R.id.progress);

pb.setVisibility(View.VISIBLE);

}


@Override

protected void onPostExecute (MyBean myBean) {

super. onPostExecute (myBean);

Toast.makeText(context.getApplicationContext (),«The profile has been saved",Toast.LENGTH_SHORT).show ();

SharedPreferences. Editor editor = mSettings. edit ();

editor. putString («APP_PREFERENCES_PHOTO_URL», myBean.getMImage ());

editor.commit ();

pb.setVisibility(View.INVISIBLE);

}


@Override

protected void onProgressUpdate (Integer… values) {

super. onProgressUpdate (values);

}


@Override

protected MyBean doInBackground (MyBean… params) {

MyBean profile=params [0];

MyBean response=null;

if (myApiService == null) {

MyApi. Builder builder = new MyApi.Builder(AndroidHttp.newCompatibleTransport (),

new AndroidJsonFactory (), null)

.setRootUrl (»https://meet-love-android.appspot.com/_ah/api/")

.setGoogleClientRequestInitializer (new GoogleClientRequestInitializer () {

@Override

public void initialize (AbstractGoogleClientRequest <?> abstractGoogleClientRequest) throws IOException {

abstractGoogleClientRequest.setDisableGZipContent (true);

}

});

myApiService = builder. build ();

}


try {

response=myApiService.setProfile (profile).execute ();

} catch (IOException e) {

}

return response;

}

}

Получение изображения:

import com.google.api.server.spi.config. Api;

import com.google.api.server.spi.config. ApiMethod;

import com.google.api.server.spi.config. ApiNamespace;

import com. google. appengine. api. blobstore. BlobInfo;

import com. google. appengine. api. blobstore. BlobInfoFactory;

import com. google. appengine. api. blobstore. BlobKey;

import com. google. appengine. api. blobstore. BlobstoreService;

import com. google. appengine. api. blobstore. BlobstoreServiceFactory;

import com. google. appengine. api. datastore. DatastoreService;

import com. google. appengine. api. datastore. DatastoreServiceFactory;

import com. google. appengine. api. datastore. Entity;

import com. google. appengine. api. datastore. EntityNotFoundException;

import com.google.appengine.api.datastore.Key;

import com.google.appengine.api.datastore.KeyFactory;

import com.google.appengine.api.images.ImagesService;

import com.google.appengine.api.images.ImagesServiceFactory;

import com.google.appengine.api.images.ServingUrlOptions;


import org.apache.commons.codec.binary.Base64;

import org.apache.commons.io.IOUtils;

import org.apache.http.HttpEntity;

import org.apache.http.entity.ContentType;

import org.apache.http.entity.mime.MultipartEntityBuilder;


import java.io.IOException;

import java.net.HttpURLConnection;

import java.net. URL;

import java.util.Iterator;


@Api (

name = «myApi»,

version = «v1»,

namespace = @ApiNamespace (

ownerDomain = "backend.com»,

ownerName = "backend.com»,

packagePath=»»

)

)

public class MyEndpoint {

private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService ();


@ApiMethod (

name = «setProfile»,

httpMethod = ApiMethod.HttpMethod.POST

)


public MyBean setProfile (MyBean profile) {

String accountName=profile.getmAccount ();

Key key = KeyFactory.createKey («User», accountName);

Entity user=null;

try {

user = datastore.get (key);

} catch (EntityNotFoundException e) {

e.printStackTrace ();

}

if (user==null) {

user = new Entity («User», accountName);

}

byte [] imageAsBytes = Base64.decodeBase64(profile.getmImage ());

BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService ();


BlobInfoFactory bf = new BlobInfoFactory ();

Iterator itr = bf. queryBlobInfos ();

while (itr. hasNext ()) {

BlobInfo bi = (BlobInfo)itr.next ();

if (bi.getFilename().equals(accountName+".jpeg»)) {

blobService.delete(bi.getBlobKey ());

}

}


String uploadUrl = blobService.createUploadUrl (»/blob/upload»);

HttpEntity requestEntity = MultipartEntityBuilder.create ()

.addBinaryBody («file», imageAsBytes, ContentType.create («image/jpg»), accountName+".jpeg»)

.build ();


try {

URL url = new URL (uploadUrl);

HttpURLConnection connection = (HttpURLConnection) url. openConnection ();

connection.setDoOutput (true);

connection.setRequestMethod («POST»);

connection.addRequestProperty («Content-length», requestEntity.getContentLength () + «»);

connection.addRequestProperty(requestEntity.getContentType().getName (), requestEntity.getContentType().getValue ());

requestEntity.writeTo(connection.getOutputStream ());

String responseBody = IOUtils.toString(connection.getInputStream ());


if(connection.getResponseCode () <200 || connection.getResponseCode ()> = 400) {

throw new IOException («HTTP Status " + connection.getResponseCode () + ": " + connection.getHeaderFields () + "n» + responseBody);

}


BlobKey blobKey = new BlobKey (responseBody);

ImagesService imagesService = ImagesServiceFactory.getImagesService ();

ServingUrlOptions servingOptions = ServingUrlOptions. Builder. withBlobKey (blobKey);


String servingUrl = imagesService.getServingUrl (servingOptions);

user.setProperty («mBlobKey», responseBody);

user.setProperty («mServingUrl», servingUrl);

profile.setmImage (servingUrl);

} catch (Exception e) {

e.printStackTrace ();

}

datastore. put (user);

return profile;

}

}

import com. google. appengine. api. blobstore. BlobKey;

import com. google. appengine. api. blobstore. BlobstoreService;

import com. google. appengine. api. blobstore. BlobstoreServiceFactory;


import java.io.IOException;

import java.io.PrintWriter;

import java.util.List;


import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public class BlobUploadServlet extends HttpServlet {

@Override

public void doPost (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

BlobstoreService blobService = BlobstoreServiceFactory.getBlobstoreService ();

List <BlobKey> blobs = blobService.getUploads(req).get («file»);

if (blobs == null || blobs.isEmpty ()) throw new IllegalArgumentException («No blobs given»);


BlobKey blobKey = blobs.get (0);

res.setStatus(HttpServletResponse.SC_OK);

res.setContentType («text/plain»);

PrintWriter out = res.getWriter ();

out.print(blobKey.getKeyString ());

out. flush ();

out.close ();

}

}

Fragment + GoogleMap

Файл app_bar_main. xml:

<?xml version=«1.0» encoding=«utf-8»? >

<android.support.design.widget.CoordinatorLayout

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/bar_main»

android: layout_width=«match_parent»

android: layout_height=«match_parent»

android: fitsSystemWindows=«true»

tools:context="com.tmsoftstudio.meetlove.MainActivity»>


<android.support.design. widget. AppBarLayout

android: layout_width=«match_parent»

android: layout_height=«wrap_content»

android: theme="@style/AppTheme. AppBarOverlay»>


<android.support.v7.widget.Toolbar

android: id="@+id/toolbar»

android: layout_width=«match_parent»

android: layout_height=»? attr/actionBarSize»

android: background=»? attr/colorPrimary»

app: popupTheme="@style/AppTheme. PopupOverlay»

/>


</android.support.design. widget. AppBarLayout>


<RelativeLayout

android: layout_width=«match_parent»

android: layout_height=«match_parent»

android: paddingBottom="@dimen/activity_vertical_margin»

android: paddingLeft="@dimen/activity_horizontal_margin»

android: paddingRight="@dimen/activity_horizontal_margin»

android: paddingTop="@dimen/activity_vertical_margin»

app: layout_behavior="@string/appbar_scrolling_view_behavior»

android: id="@+id/content»

>


</RelativeLayout>


<android.support.design. widget. FloatingActionButton

android: id="@+id/fab»

android: layout_width=«wrap_content»

android: layout_height=«wrap_content»

android: layout_gravity=«bottom|end»

android: layout_margin="@dimen/fab_margin»

android: src="@android: drawable/ic_input_add»

app: layout_anchor="@id/content»

app: layout_anchorGravity=«top|start»

/>


</android.support.design.widget.CoordinatorLayout>

Файл activity_maps. xml:

RelativeLayout

xmlns: android="http://schemas.android.com/apk/res/android"

android: layout_width=«wrap_content»

android: layout_height=«wrap_content»

android: id="@+id/map_container»>


<fragment

xmlns: map="http://schemas.android.com/apk/res-auto"

android: id="@+id/map»

android:name="com.google.android.gms.maps.SupportMapFragment»

android: layout_width=«wrap_content»

android: layout_height=«wrap_content»

/>

</RelativeLayout>

Код фрагмента:

import android.content.Context;

import android. os. Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentManager;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;


import com.google.android.gms.maps.CameraUpdateFactory;

import com.google.android.gms.maps. GoogleMap;

import com.google.android.gms.maps. OnMapReadyCallback;

import com.google.android.gms.maps.SupportMapFragment;

import com.google.android.gms.maps. UiSettings;

import com.google.android.gms.maps.model.LatLng;

import com.google.android.gms.maps.model.MarkerOptions;


public class ViewMapFragment extends Fragment implements OnMapReadyCallback {


private static final String ARG_PARAM = «param»;


private String mParam;

private GoogleMap mMap;

private SupportMapFragment fragment;


private OnViewMapFragmentInteractionListener mListener;


public ViewMapFragment () {

// Required empty public constructor

}


public static ViewMapFragment newInstance (String param) {

ViewMapFragment fragment = new ViewMapFragment ();

Bundle args = new Bundle ();

args. putString (ARG_PARAM, param);

fragment.setArguments (args);

return fragment;

}


@Override

public void onCreate (Bundle savedInstanceState) {

super. onCreate (savedInstanceState);

if (getArguments ()!= null) {

mParam = getArguments().getString (ARG_PARAM);

}

}


@Override

public View onCreateView (LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

// Inflate the layout for this fragment

View view= inflater.inflate(R.layout.activity_maps, container, false);

return view;

}


@Override

public void onActivityCreated (Bundle savedInstanceState) {

super. onActivityCreated (savedInstanceState);

FragmentManager fm = getChildFragmentManager ();

fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);

if (fragment == null) {

fragment = SupportMapFragment.newInstance ();

fm.beginTransaction().replace(R.id.map_container, fragment).commit ();

}

fragment.getMapAsync (this);


}


@Override

public void onMapReady (GoogleMap googleMap) {

mMap = googleMap;

UiSettings settings = mMap.getUiSettings ();

settings.setZoomControlsEnabled (true);


LatLng sydney = new LatLng (-34, 151);

mMap.addMarker (new MarkerOptions ().position (sydney).title («Marker in Sydney»));

mMap.animateCamera(CameraUpdateFactory.newLatLngZoom (sydney, 14.0f));

}


public void onViewMapPressed () {

if (mListener!= null) {

mListener. onViewMapFragmentInteraction ();

}

}


@Override

public void onAttach (Context context) {

super. onAttach (context);

if (context instanceof OnViewMapFragmentInteractionListener) {

mListener = (OnViewMapFragmentInteractionListener) context;

} else {

throw new RuntimeException(context.toString ()

+ " must implement OnFragmentInteractionListener»);

}

}


@Override

public void onDetach () {

super. onDetach ();

mListener = null;

}


public interface OnViewMapFragmentInteractionListener {

void onViewMapFragmentInteraction ();

}

}

Вызов фрагмента:

FragmentManager fragmentManager = getSupportFragmentManager ();

FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction ();

ViewMapFragment fragmentMap = new ViewMapFragment ();

fragmentTransaction.replace(R.id.content, fragmentMap);

fragmentTransaction.addToBackStack (null);

fragmentTransaction.commit ();

fab. hide ();

Файл манифеста:

<uses-permission android:name="android.permission.INTERNET» />

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE» />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION» />


<meta-data

android:name="com.google.android.geo. API_KEY»

android: value="@string/google_maps_key» />

Файл google_maps_api. xml:

<resources>

<string name=«google_maps_key» templateMergeStrategy=«preserve» translatable=«false»>

Aiza…

</string>

</resources>


Страницы книги >> Предыдущая | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Следующая
  • 0 Оценок: 0

Правообладателям!

Это произведение, предположительно, находится в статусе 'public domain'. Если это не так и размещение материала нарушает чьи-либо права, то сообщите нам об этом.


Популярные книги за неделю


Рекомендации